警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

在表格视图中展示数据

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

../_images/relationaltable1.png

以下示例基于SQL数据模型创建一个视图:

view = QTableView()
view.setModel(model)
view.show()
view = QTableView()
view.setModel(model)

如果模型是读写模型(例如,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 的左侧还有一个垂直标题,其中包含标识行的数字。如果您使用 insertRows() 以编程方式插入行,新行将用星号 (*) 标记,直到使用 submitAll() 提交或当用户移动到另一条记录时自动提交(假设 edit strategyOnRowChange)。

../_images/insertrowinmodelview.png

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

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

QSqlTableModel 被优化为一次操作一个表。如果你需要一个可以操作任意结果集的可读写模型,你可以子类化 QSqlQueryModel 并重新实现 flags() 和 setData() 以使其可读写。以下两个函数使查询模型的字段1和字段2可编辑:

Qt.ItemFlags EditableSqlModel.flags(QModelIndex index)

    Qt.ItemFlags flags = QSqlQueryModel.flags(index)
    if index.column() == 1 or index.column() == 2:
        flags |= Qt.ItemIsEditable
    return flags

def setData(self, QModelIndex index, QVariant value, int /* role */):

    if index.column() < 1 or index.column() > 2:
        return False
    primaryKeyIndex = QSqlQueryModel.index(index.row(), 0)
    id = data(primaryKeyIndex).toInt()
    clear()
    ok = bool()
    if index.column() == 1:
        ok = setFirstName(id, value.toString())
else:
        ok = setLastName(id, value.toString())
    refresh()
    return ok

setFirstName() 辅助函数的定义如下:

def setFirstName(self, int personId, QString firstName):

    query = QSqlQuery()
    query.prepare("update person set firstname = ? where id = ?")
    query.addBindValue(firstName)
    query.addBindValue(personId)
    return query.exec()

setLastName() 函数类似。查看 查询模型 示例以获取完整的源代码。

子类化模型使得可以以多种方式自定义它:您可以为项目提供工具提示,更改背景颜色,提供计算值,为查看和编辑提供不同的值,特殊处理空值等。有关详细信息,请参阅模型/视图编程以及QAbstractItemView参考文档。

如果你只需要将外键解析为更人性化的字符串,你可以使用QSqlRelationalTableModel。为了获得最佳效果,你还应该使用QSqlRelationalDelegate,这是一个为编辑外键提供组合框编辑器的委托。

../_images/relationaltable1.png

关系表模型示例展示了如何结合使用QSqlRelationalTableModelQSqlRelationalDelegate来提供支持外键的表。