Таблица базы данных (файл examples-qt/db01/db01.cpp)
1 // Таблица базы данных 2 3 #include <QtGui>
4 #include <QtSql>
5 6 int main(int argc, char *argv[]) { 7 8 QApplication app(argc, argv);
9 10 QTextCodec *codec = QTextCodec::codecForName("CP1251");
11 QTextCodec::setCodecForTr(codec);
12 QTextCodec::setCodecForCStrings(codec);
13 QTextCodec::setCodecForLocale(codec);
14 15 QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
16 db.setDatabaseName("mysql_db1");
17 db.setUserName("");
18 db.setPassword("");
19 db.open();
20 21 // QSqlQuery q; 22 // Для корректного отображения символов кириллицы, 23 // возможно, придётся установить кодировку: 24 // q.exec(QObject::tr("SET NAMES 'cp1251'"));
25 26 QSqlTableModel *model = new QSqlTableModel();
27 model->
setTable("employee");
28 29 model->
insertRows(0, 1);
30 model->
setData(model->
index(0, 0), 159);
31 model->
setData(model->
index(0, 1), QObject::tr("Сова"));
32 model->
setData(model->
index(0, 2), QDate(1985, 12, 31));
33 model->
setData(model->
index(0, 3), 12.34);
34 model->
setData(model->
index(0, 4), 1);
35 model->
submitAll();
36 37 model->
setEditStrategy(QSqlTableModel::OnFieldChange);
38 39 model->
select();
40 model->
setHeaderData(0, Qt::Horizontal, 41 QObject::tr("Табельн.\nномер"));
42 model->
setHeaderData(1, Qt::Horizontal, 43 QObject::tr("Имя"));
44 model->
setHeaderData(2, Qt::Horizontal, 45 QObject::tr("День рождения"));
46 model->
setHeaderData(3, Qt::Horizontal, 47 QObject::tr("Зарплата"));
48 model->
setHeaderData(4, Qt::Horizontal, 49 QObject::tr("Женат/\nзамужем"));
50 51 QTableView *view = new QTableView();
52 view->
setModel(model);
53 54 view->
setAlternatingRowColors(true);
55 view->
resizeRowsToContents();
56 view->
resizeColumnsToContents();
57 view->
show();
58 59 return app.exec();
60 }
(15-19) Установили параметры соединения и подключились к базе данных. (21-24) При необходимости сообщили серверу кодировку строковых данных, которую использует наша программа. (26-27) Создали модель QSqlTableModel и задали имя таблицы БД. (29-35) Добавили к таблице новую строку, задали значения всех пяти ячеек этой строки и подтвердили запись изменений в базу данных (диагностика возможных ошибок для простоты опущена). (37) Задали режим обновления данных в БД при редактировании таблицы: параметр QSqlTableModel::OnFieldChange означает, что запись изменений в базу данных будет выполняться автоматически после окончания редактирования очередной ячейки. Другие возможные режимы: QSqlTableModel::OnRowChange (при переходе к другой строке) и QSqlTableModel::OnManualSubmit (при выполнении метода submitAll, подтверждающего все изменения, или revertAll, отменяющего их). (39) Выбрали данные из таблицы БД. (40-49) Определили заголовки столбцов, которые будут отображаться в окне. (51-52) Создали представление и задали для него модель. (54) Установили чередующийся цвет фона для строк таблицы. (55-56) Выполнили автоподстройку высоты строк и ширины столбцов. (57) Вывели представление таблицы на экран.
Проверьте, как работает эта програма: можно изменять данные в ячейках, при редактировании чисел и дат автоматически отображаются кнопки инкремента/декремента. Но поскольку для элемента QDoubleSpinBox по умолчанию задано максимальное значение 99.99, то при попытке изменить, например, величину зарплаты работника, любое значение, большее этого максимального, автоматически усекается. Разумеется, попытка ввести число больше допустимого, оканчивается неудачей. Кроме того, после редактирования первой же ячейки таблицы, когда происходит автоматическое обновление данных, ширина столбцов и высота строк изменяется, т.к. размеры ячеек по умолчанию отличаются от тех, что установились в результате однократного выполнения методов resizeRowsToContents и resizeColumnsToContents.
Если мы хотим получать большую зарплату, выводить разные столбцы различным цветом, отображать галочки для полей логического типа, использовать календарик для ввода дат, в общем, как-то изменять заданные по умолчанию параметры отображения и редактирования ячеек, то у нас имеются две возможности: разрабатывать свой класс модели и/или представления таблицы или использовать специальные объекты-делегаты для её ячеек. Рассмотрим оба варианта по очереди.
Работа с таблицами баз данных
Самый простой способ отображения информации базы данных в виде таблицы заключается в использовании классов QSqlQueryModel и QTableView: QSqlQueryModel model; model.setQuery("select * from employee");
QTableView view; view.setModel(&model); view.show();
Но вместо QsqlQueryModel можно использовать класс QSqlTableModel, позволяющий работать с таблицами баз данных на более высоком уровне, чем выполнение SQL-запросов. Тогда приведённый выше фрагмент кода запишется следующим образом: QSqlTableModel model; model.setTable("employee"); model.select();
QTableView view; view.setModel(&model); view.show(); Более сложный пример: вместо выполнения SQL-запроса SELECT * FROM employee WHERE salary >= 1000 ORDER BY id DESC достаточно задать фильтр и условие сортировки: QSqlTableModel model = QSqlTableModel(parent, db); model.setTable("employee"); // Имя таблицы базы данных. model.setFilter("salary >= 1000"); // Условие WHERE. model.setSort(0, Qt::DescendingOrder); // Сортировка по убыванию id. model.select(); // Получить данные.
После определения модели можно узнать значение любого поля любой записи, например: QString name = model.record(i).value("name").toString(); или int salary = model.data(model.index(i, 3)).toInt();
Для перебора всех записей набора данных: for (int i = 0; i < model.rowCount(); ++i) { QSqlRecord record = model.record(i); QString name = record.value("name").toString(); double salary = record.value("salary").toDouble(); ....... }
В листинге приведён пример работы с таблицей работников, созданной в результате выполнения предыдущей программы, а на рис. показан внешний вид таблицы в системе Windows.