Python Qt:QabstracteModel中的setData方法

Python Qt:QabstracteModel中的setData方法,python,qt,qtgui,qabstractitemmodel,qabstractlistmodel,Python,Qt,Qtgui,Qabstractitemmodel,Qabstractlistmodel,我是model view的新手,在查看文档的同时,我一直在关注以下内容,我偶然发现了这个小细节:可以下载的教程代码在QAbstractItemModel类(此处为QAbstractListModel)中包含setData方法,其代码为: def setData(self, index, value, role = QtCore.Qt.EditRole): if role == QtCore.Qt.EditRole: row = index.row() c

我是model view的新手,在查看文档的同时,我一直在关注以下内容,我偶然发现了这个小细节:可以下载的教程代码在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
我意识到如果color.isValid()函数返回False,视图仍然会得到更新。我是否误解了setData方法中的返回角色,或者它是一个bug

作为参考,我使用的是PySide1.2.1,而不是PyQt4

我是否误解了setData方法中的返回角色,或者它是一个bug

从Qt:

bool qabstractemmodel::setData(常量QModelIndex&index,常量QVariant&value,int-role=Qt::EditRole)[virtual]

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

如果成功,则返回true;否则返回false

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

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

然而,即使没有根据返回值成功设置数据,您似乎也会发出dataChanged()信号。另外,您似乎参考的教程正在使用代码中设置的
self.\u 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

引用有关
setData
的视频教程:

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

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

查看Qt源代码,
setData
的返回值确实会在一些地方进行检查,其中一些检查有时会帮助触发更新。但是实际上有几十种东西可以触发更新,因此
setData
的返回值对于更新项目来说绝对不是必需的


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

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

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

例如,假设您使用
QLineEdit
s和
QDataWidgetMapper
设计了一个表单,以将表单内容映射到您的模型。我们还假设
QDataWidgetMapper::SubmitPolicy
设置为
AutoSubmit
。在
AutoSubmit
模式下,每次编辑
QLineEdit
然后失去焦点时,模型都会更新。如果模型也拒绝更改,并且当前数据(sans change)被重新填充到
QLineEdit
,这将导致用户不得不重新开始(而不是修复其条目)

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

我可以立即想到两种方法来改变这种行为:

  • 通过发出视图可以连接并用于更新自身的自定义
    dataRejected
    信号,创建处理
    setData
    ->
    false
    的自定义委托
  • 为您的模型创建一个“无状态”视图:强制视图在任何时候更新自身时从模型检索数据。以这种方式,提交对模型的潜在更改不会更新视图,除非该模型发出
    dataChanged
    信号,在这种情况下,视图将检索当前状态并更新自身

  • 谢谢,但我不明白的是,如果一切都与dataChanged信号有关,为什么需要返回True或False?@IlyesFerchiou:这样调用方就可以检查更新是否成功。他们不处理信号。它们只剩下返回值。感谢您的回答,但我刚刚删除了dataChanged信号线,行为仍然相同,即使返回False也会反映修改。我想我评论得太快了。所以我们回到了起点。@IlyesFerchiou:我无法复制你的问题。请确保从零开始,请使用我粘贴的代码。删除数据更改时唯一更改的是,只有我进行修改的视图得到更新,使用相同模型的其他视图在我用鼠标设置焦点之前没有更新。谢谢,这是我想知道的。所以,如果设置不正确,它最终可能会在某个地方出错。@IlyesFerchiou:这是我写的,但有很多细节。:)你不是