在表格视图中呈现数据

QSqlQueryModel 、QSqlTableModel 和QSqlRelationalTableModel 类可作为 Qt 视图类(如QListView 、QTableView 和QTreeView )的数据源。实际上,QTableView 是最常见的选择,因为 SQL 结果集本质上是一种二维数据结构。

显示 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 )。

在模型中插入一行

同样地,如果您使用removeRows() 删除行,这些行将被标记为感叹号 (!),直到更改被提交为止。

视图中的项目通过委托进行渲染。默认委托QStyledItemDelegate 处理最常见的数据类型(int 、QString 、QImage 等)。当用户开始编辑视图中的项目时,该委托还负责提供编辑控件(例如下拉列表框)。 您可以通过继承QAbstractItemDelegate 或QStyledItemDelegate 来创建自己的委托类。更多信息请参阅《模型/视图编程》。

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`——这是一个提供下拉列表编辑器以编辑外键的委托。

编辑关系表中的外键

“关系表模型”示例演示了如何将QSqlRelationalTableModel 与QSqlRelationalDelegate 结合使用,为表提供外键支持。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.