Spec-Zone.ru › Qt 5.11

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

Классы 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 и т. д.). Делегат также отвечает за предоставление виджетов-редакторов (например, combobox) при начале редактирования пользователем элемента в представлении. Вы можете создать собственные делегаты, наследуя от 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, делегат, который предоставляет редакторы combobox для редактирования внешних ключей.

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/archives/qt-5.11/sql-presenting.html

Spec-Zone.ru

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