Qt 如何在QAbstractTableModel内设置数据

Qt 如何在QAbstractTableModel内设置数据,qt,qtableview,qabstracttablemodel,Qt,Qtableview,Qabstracttablemodel,我需要用Qt实现一个表 我相信我会起诉一个QAbstractTableModel,而QTableView使用这个模型 我知道我必须编辑模型的rowCount()、columnCount()和data()函数 但是,我不明白如何在模型中准确地设置数据,以便data()函数能够检索它 是否为此目的提供了setData()函数?我已经看到它将EditRole作为其参数,我不希望这样,因为我不希望我的表是可编辑的 那么,如何使用data()函数在模型内部“设置”数据,或者为模型获取数据 另外,data(

我需要用Qt实现一个表

我相信我会起诉一个QAbstractTableModel,而QTableView使用这个模型

我知道我必须编辑模型的rowCount()、columnCount()和data()函数

但是,我不明白如何在模型中准确地设置数据,以便data()函数能够检索它

是否为此目的提供了setData()函数?我已经看到它将EditRole作为其参数,我不希望这样,因为我不希望我的表是可编辑的

那么,如何使用data()函数在模型内部“设置”数据,或者为模型获取数据

另外,data()函数是如何调用的,即谁调用它,需要在哪里调用它

请帮我做这个


谢谢。

如何将实际数据保存在内存中、从数据存储中生成或查询完全取决于您。如果是静态数据,则可以使用或自定义数据结构

对于可编辑模型,只需重新实现
setData()
方法

您需要在不可编辑的
QAbstractTableModel
子类中实现4种方法:

  • int rowCount()
  • int columnCount()
  • QVariant headerData(int节,Qt::Orientation-Orientation,int-role=Qt::DisplayRole)
  • QVariant数据(常量QModelIndex&index,int-role=Qt::DisplayRole)
这些方法是从视图调用的,通常是
QTableView
实例。前两个方法应该返回表的维度。例如,如果
rowCount()
返回
10
columnCount()
返回
4
,视图将调用
data()
方法40次(每个单元格一次),请求模型内部数据结构中的实际数据

例如,假设您在模型中实现了一个自定义槽
RetrieveDataFromMarsCriosity()
。此插槽填充数据结构,并连接到
QPushButton
实例,因此您可以通过单击按钮获得新数据。 现在,您需要让视图知道数据何时被更改,以便它能够正确更新。这就是为什么需要发出
beginRemoveRows()
endRemoveRows()
beginInsertRows()
endInsertRows()
及其对应列


您不需要使用
setData(…)
。相反,您需要子类化
QAbstractTableModel
,使其方法
rowCount()
columnCount()
数据(索引)
,并可能
头数据(节,水平或垂直)
返回您希望显示的数据。下面是一个基于PyQt5的示例:

从PyQt5.QtWidgets导入*
从PyQt5.QtCore导入*
标题=[“科学家姓名”、“生日”、“贡献”]
行=[(“牛顿”,“1643-01-04”,“经典力学”),
(《爱因斯坦》,《1879-03-14》,《相对论》),
(“达尔文”,“1809-02-12”,“进化论”)]
类TableModel(QAbstractTableModel):
def行数(自身、父级):
#有几排?
返回长度(行)
def列数(自身、父项):
#有多少列?
返回长度(标题)
def数据(自身、索引、角色):
如果角色!=Qt.DisplayRole:
返回QVariant()
#给定索引处的单元格值是多少?
返回行[index.row()][index.column()]
def headerData(自身、部门、方向、角色):
如果角色!=Qt.display角色或方向!=Qt.水平:
返回QVariant()
#给定列的标题是什么?
返回标题[部分]
app=QApplication([])
model=TableModel()
view=QTableView()
view.setModel(model)
view.show()
app.exec()
它取自此,并显示下表:


非常感谢您的及时帮助。我一定会调查的。@dschulz,第一次初始化是否绝对需要使用beginInsertRows()等?那么我不明白dataChanged()的用途。为什么Qt无法仅使用rowCount()、columnCount()和data()检索信息?为什么需要使用beginInsertRows()等创建行和列?@Cool\u Coder是的,如果重新实现
insertRows()
,则有必要创建行和列。在将项添加到模型的数据容器(无论是
QList
还是您使用的任何容器类)之前,必须调用
beginInsertRows()
。请注意,“数据更改”并不一定意味着正在添加或删除行或列
dataChanged()
表示模型中现有项中的数据已更新,因此视图可以检索更新的数据。试想一下,在可编辑的
QTableView
单元格中更正名称时会发生什么情况。但是,等一下,我认为在初始化模型的过程中,在模型的数据存储中插入项时,调用
beginInsertRows()
endInsertRows()
并不是绝对必要的,特别是如果你还没有将模型附加到视图上。在上面工作了2天&终于让它工作了!看起来如果我们不使用begin…()&end…(),模型不会创建内部索引。因此,我得到了无效的模型索引。感谢您提供有关dataChanged()的信息。直到现在,我发现Qt的帮助非常好,但不知何故,我觉得它们在模型/视图体系结构方面可以做得更好。这让一个新的程序员感到困惑…谢谢你。帮助很大。