在表格视图中展示数据

以下类(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);

您可以使用相同的模型作为多个视图的数据源。如果用户通过其中一个视图编辑模型,则其他视图将立即反映这些更改。TableModel 示例显示了其工作原理。

视图类在顶部显示一个标题来标记列。要更改标题文本,请在模型上调用 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() 删除行,则行将使用感叹号 (!) 标记,直到提交更改。

视图中的项使用委托进行渲染。默认委托 QStyledItemDelegate 处理最常见的数据类型(如 int、QString、QImage 等)。委托还负责在用户开始编辑视图中的项时提供编辑小部件(例如组合框)。您可以通过扩展 QAbstractItemDelegate 或 QStyledItemDelegate 创建自己的委托。有关更多信息,请参阅 Model/View 编程。

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

关系表模型示例说明如何结合使用 QSqlRelationalTableModelQSqlRelationalDelegate 以提供支持外键的表。

© 2024 Qt 公司有限公司。此处包含的文档贡献归各自所有者所有。此处提供的文档根据 GNU 自由文档许可证 1.3 版本 的条款发布,由自由软件基金会发布。Qt 及相关标志是芬兰的 Qt 公司以及全球其他国家的商标。所有其他商标均为其各自所有者的财产。