Spec-Zone.ru › Qt 6.0

Представление данных в виде таблицы

Классы 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() или автоматически, когда пользователь переходит к другой записи (при условии, что стратегия редактирования равна 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-6.0/sql-presenting.html

Spec-Zone.ru

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