Spec-Zone.ru › Qt 5.15

Представление данных в табличном виде

Классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel могут использоваться в качестве источника данных для классов представлений Qt, таких как QListView, QTableView и QTreeView. На практике QTableView является наиболее распространённым выбором, поскольку набор результатов SQL по своей сути представляет собой двумерную структуру данных.

A table view displaying a QSqlTableModel

Следующий пример создаёт представление на основе модели данных SQL:

    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

Если модель является моделью чтения-записи (например, QSqlTableModel), представление позволяет пользователю редактировать поля. Это можно отключить, вызвав

    view->setEditTriggers(QAbstractItemView::NoEditTriggers);

Вы можете использовать одну и ту же модель в качестве источника данных для нескольких представлений. Если пользователь редактирует модель через одно из представлений, другие представления немедленно отражают изменения. Пример Модели таблиц демонстрирует, как это работает.

Классы представлений отображают заголовок в верхней части для маркировки столбцов. Чтобы изменить текст заголовков, вызовите 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() или автоматически, когда пользователь переходит к другой записи (при условии, что стратегия редактирования EditStrategy — QSqlTableModel::OnRowChange).

Inserting a row in a model

Аналогично, если вы удаляете строки, используя 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() аналогична. Полный исходный код см. в примере Модели запросов.

Наследование от модели позволяет настроить её множеством способов: вы можете предоставить всплывающие подсказки для элементов, изменить цвет фона, предоставить рассчитанные значения, предоставить разные значения для просмотра и редактирования, специально обработать нулевые значения и многое другое. Подробную информацию см. в разделе Программирование моделей/представлений, а также в справочной документации по QAbstractItemView.

Если вам нужно только преобразовать внешний ключ в более понятную строку, вы можете использовать QSqlRelationalTableModel. Для достижения наилучших результатов рекомендуется также использовать QSqlRelationalDelegate, делегата, который предоставляет редакторы раскрывающихся списков для редактирования внешних ключей.

Editing a foreign key in a relational table

Пример Модели реляционных таблиц демонстрирует, как использовать QSqlRelationalTableModel в сочетании с QSqlRelationalDelegate для предоставления таблиц с поддержкой внешних ключей.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/sql-presenting.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API