Представление данных в табличном виде
Классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel могут использоваться в качестве источника данных для классов представлений Qt, таких как QListView, QTableView и QTreeView. На практике QTableView является наиболее распространённым выбором, поскольку результат запроса SQL представляет собой по сути двумерную структуру данных.
Следующий пример создаёт представление на основе модели данных SQL:
QTableView *view = new QTableView;
view->setModel(model);
view->show();
Если модель является моделью чтения-записи (например, QSqlTableModel), представление позволяет пользователю редактировать поля. Вы можете отключить это, вызвав
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
Вы можете использовать одну и ту же модель в качестве источника данных для нескольких представлений. Если пользователь редактирует модель через одно из представлений, другие представления немедленно отобразят изменения. Пример Table Model демонстрирует, как это работает.
Классы представлений отображают заголовок вверху для маркировки столбцов. Чтобы изменить текст заголовка, вызовите setHeaderData() в модели. Значения по умолчанию для заголовков — имена полей таблицы. Например:
model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("City"));
model->setHeaderData(3, Qt::Horizontal, QObject::tr("Country"));
QTableView также имеет вертикальный заголовок слева с номерами, определяющими строки. Если вы вставляете строки программно с помощью QSqlTableModel::insertRows(), новые строки будут помечены звездочкой (*) до тех пор, пока они не будут отправлены с помощью submitAll() или автоматически, когда пользователь переходит к другой записи (предполагая, что стратегия редактирования edit strategy равна QSqlTableModel::OnRowChange).
Аналогично, если вы удаляете строки с помощью removeRows(), строки будут помечены восклицательным знаком (!) до тех пор, пока изменение не будет отправлено.
Элементы в представлении отрисовываются с помощью делегата. Делегат по умолчанию, QItemDelegate, обрабатывает наиболее распространённые типы данных (int, QString, QImage и т. д.). Делегат также отвечает за предоставление виджетов редактирования (например, раскрывающегося списка) при начале редактирования элемента в представлении. Вы можете создать собственные делегаты, наследуя от QAbstractItemDelegate или QItemDelegate. Дополнительную информацию см. в разделе Моделирование/Представление.
QSqlTableModel оптимизирован для работы с одной таблицей за раз. Если вам нужна модель чтения-записи, работающая с произвольным набором результатов, вы можете создать подкласс QSqlQueryModel и переопределить flags() и setData(), чтобы сделать его моделью чтения-записи. Следующие две функции делают поля 1 и 2 модели запроса редактируемыми:
Qt::ItemFlags EditableSqlModel::flags(
const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 1 || index.column() == 2)
flags |= Qt::ItemIsEditable;
return flags;
}
bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
{
if (index.column() < 1 || index.column() > 2)
return false;
QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
int id = data(primaryKeyIndex).toInt();
clear();
bool ok;
if (index.column() == 1) {
ok = setFirstName(id, value.toString());
} else {
ok = setLastName(id, value.toString());
}
refresh();
return ok;
}
Функция-помощник setFirstName() определена следующим образом:
bool EditableSqlModel::setFirstName(int personId, const QString &firstName)
{
QSqlQuery query;
query.prepare("update person set firstname = ? where id = ?");
query.addBindValue(firstName);
query.addBindValue(personId);
return query.exec();
}
Функция setLastName() аналогична. Полный исходный код см. в примере Query Model.
Наследование от модели позволяет настроить её многими способами: можно предоставить всплывающие подсказки для элементов, изменить цвет фона, предоставить рассчитанные значения, предоставить разные значения для просмотра и редактирования, особенно обработать пустые значения и многое другое. Дополнительную информацию см. в разделе Моделирование/Представление, а также в справочной документации QAbstractItemView.
Если вам нужно только преобразовать внешний ключ в более удобочитаемую строку, вы можете использовать QSqlRelationalTableModel. Для достижения наилучших результатов следует также использовать QSqlRelationalDelegate, делегат, который предоставляет виджеты раскрывающегося списка для редактирования внешних ключей.
Пример Relational Table Model демонстрирует, как использовать QSqlRelationalTableModel совместно с QSqlRelationalDelegate для предоставления таблиц с поддержкой внешних ключей.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/sql-presenting.html