Spec-Zone.ru › Qt 6.1

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

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

Spec-Zone.ru

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