6

我是模型视图的新手,我在查看文档的同时一直在关注本教程,我偶然发现了这个小细节:可以在此处下载的教程代码在 QAbstractItemModel 类(此处为 QAbstractListModel)中setData 方法的代码是:

def setData(self, index, value, role = QtCore.Qt.EditRole):
    if role == QtCore.Qt.EditRole:

        row = index.row()
        color = QtGui.QColor(value)

        if color.isValid():
            self.__colors[row] = color
            self.dataChanged.emit(index, index)
            return True
    return False

根据教程中的解释以及我从文档中了解的内容,如果函数返回 True,则更新视图,如果返回 false,则没有任何反应,但是当我将代码更改为:

def setData(self, index, value, role = QtCore.Qt.EditRole):
    if role == QtCore.Qt.EditRole:

        row = index.row()
        color = QtGui.QColor(value)

        if color.isValid():
            self.__colors[row] = color
            self.dataChanged.emit(index, index)
            return False # This is what I changed in the code
    return False

我意识到即使函数返回 False,如果 color.isValid() 视图仍然会更新。我误解了 setData 方法中的返回角色还是一个错误?

作为参考,我使用的是 PySide 1.2.1,而不是 PyQt4。

4

3 回答 3

3

引用有关以下内容的视频教程setData

...如果操作成功,此函数需要返回 true,否则视图将不会自行更新。

严格来说,这种说法是错误的。QAbstractItemModel的文档只说setData如果数据设置成功则返回 true,否则返回 false;它没有提到这可能会产生什么后果。具体来说,它没有提到任何关于更新视图的内容。

查看 Qt 源代码,setData 确实在一些地方检查了 的返回值,其中一些检查有时可以帮助触发更新。但是实际上有很多东西可以触发更新,所以返回值setData对于更新项目来说绝不是必不可少的。

也许说setData 应该返回 true 会更准确,否则视图可能不会自行更新(在某些情况下)。

于 2013-12-26T20:36:20.813 回答
2

我误解了 setData 方法中的返回角色还是一个错误?

从 Qt文档

bool QAbstractItemModel::setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) [虚拟]

将索引处的项目的角色数据设置为值。

成功则返回真;否则返回假。

如果成功设置数据,则应发出 dataChanged() 信号。

基类实现返回 false。必须为可编辑模型重新实现此函数和 data()。

然而,即使数据没有根据返回值成功设置,您似乎也会发出 dataChanged() 信号。此外,您似乎参考的教程是self.__colors在您的代码中为rowCount()、 `data() 和其他方法使用集合。如果您想避免更新,则需要在任何此类声明之前返回 False。

您需要注意这些标准,因为信号和颜色是内部管理的,而调用者使用返回值来查看setData()方法是否已成功设置。

基于以上知识,您应该已经编写了此代码,以便您第二次尝试使其按预期工作:

def setData(self, index, value, role = QtCore.Qt.EditRole):
    if role == QtCore.Qt.EditRole:

        row = index.row()
        color = QtGui.QColor(value)

        if color.isValid():
            return False
    return False
于 2013-12-26T12:23:59.903 回答
1

我找不到太多这方面的信息。也就是说,“Qt 专家”的这个论坛帖子表明这种行为是 Qt 开发人员的设计选择:

http://qt-project.org/forums/viewthread/31462

更具体地说,如果视图被模型拒绝,视图不会丢失您的输入。在您正在遵循的教程的上下文中,这可能看起来很奇怪(颜色变化与模型不同步),但在某些情况下,这可能是可取的。

例如,假设您使用QLineEdits设计了一个表单QDataWidgetMapper,并将表单的内容映射到您的模型。我们还假设QDataWidgetMapper::SubmitPolicy设置为AutoSubmit。在AutoSubmitmode 中,每次QLineEdit编辑然后失去焦点时,都会更新模型。如果模型也拒绝更改,并且当前数据(无更改)重新填充到 中QLineEdit,这将产生用户必须重新开始的效果(而不是修复他们的条目)。

另一种设计选择是允许视图与模型不同步,如果不希望这样做,则将更改此行为的责任推给程序员。

我可以想到的两种改变这种行为的方法是:

  1. 创建一个自定义委托来处理setData->false通过发出一个dataRejected视图可以连接并用于更新自身的自定义信号。
  2. 为您的模型创建一个“无状态”视图:强制视图在模型更新时从模型中检索数据。以这种方式,除非模型发出信号,否则向模型提交潜在更改不会更新视图dataChanged,在这种情况下,视图将检索当前状态并自行更新。
于 2014-09-01T18:44:59.360 回答