【问题标题】:Value before change?改变前的价值?
【发布时间】:2014-11-09 23:03:30
【问题描述】:

我有一个模型 QStandardItemModel 并订阅了 itemChanged() 信号,在那里我得到了更改的项目。

有什么方法可以在更改之前获取更改项目的价值?

QtCore.QObject.connect(self, QtCore.SIGNAL("itemChanged(QStandardItem *)"), self.sModelChanged)  

【问题讨论】:

  • 对不起,你的工具是什么类?是QStandardItemModel 吗?
  • 是的,对不起,我应该提一下。
  • @Ezee:感谢编辑。

标签: qt pyqt qtablewidget


【解决方案1】:

过去引用此answer。 (Qt, C++)

在阅读我的答案之前,我展示了如何在 pyqt4 中实现。这不是我的主意,但我会展示如何做到这一点。


QtGui.QStandardItemModel 类只有 void itemChanged (QStandardItem*)。因此,您必须自己创建自定义信号。

1) 对于这种情况,我建议继承类QtGui.QStandardItemModel 创建自己的类来实现获取更改前的更改项的值。

2) 接下来,覆盖bool QStandardItemModel.setData (self, QModelIndex index, QVariant value, int role = Qt.EditRole) 应该可以跟踪更改的数据(但它无法在承包商启动时跟踪)。

3) 并在设置数据之前创建自己的信号;

实现的示例(PyQt4、Python);

import sys
from PyQt4 import QtGui, QtCore

class QNonStandardItemModel (QtGui.QStandardItemModel):
    itemBeforeAndAfterChanged = QtCore.pyqtSignal(QtCore.QModelIndex, int, QtCore.QVariant, QtCore.QVariant)
    def setData (self, indexQModelIndex, afterValueQVariant, role = QtCore.Qt.EditRole):
        beforeValueQVariant = self.data(indexQModelIndex, role)
        self.itemBeforeAndAfterChanged.emit(indexQModelIndex, role, beforeValueQVariant, afterValueQVariant)
        return QtGui.QStandardItemModel.setData(self, indexQModelIndex, afterValueQVariant, role)

myQApplication = QtGui.QApplication([])
myQTreeView = QtGui.QTreeView()

headerQStandardItemModel = QNonStandardItemModel()
def callback (indexQModelIndex, role, beforeValueQVariant, afterValueQVariant):
    print '#' * 80
    print 'Before:', beforeValueQVariant.toString()
    print 'After:', afterValueQVariant.toString()
    print 'Role:', role

headerQStandardItemModel.itemBeforeAndAfterChanged.connect(callback)
headerQStandardItemModel.setHorizontalHeaderLabels([''] * 4)
myQTreeView.setModel(headerQStandardItemModel)
row1QStandardItem = QtGui.QStandardItem('ROW 1')
row1QStandardItem.appendRow([QtGui.QStandardItem(''), QtGui.QStandardItem('COLUMN 1'), QtGui.QStandardItem('COLUMN 2'), QtGui.QStandardItem('COLUMN 3')])
headerQStandardItemModel.appendRow(row1QStandardItem)

myQTreeView.show()
sys.exit(myQApplication.exec_())

【讨论】:

  • return super(QtGui.QStandardItemModel, self).setData(indexQModelIndex, afterValueQVariant, role) 没有按预期工作,我将这一行替换为 return QtGui.QStandardItemModel.setData(self, indexQModelIndex, afterValueQVariant , 角色)
  • 哦!我的错。谢谢。我在答案中修复了它。
【解决方案2】:

当QStandardItem 发生更改时,没有标准的方式来获得通知。但是,您可以轻松实现它:

  • 创建一个继承自QStandardItem的新类。
  • 重新实现 clone 以从模型中创建此类对象。
  • 重新实现setData 方法并通知项目已更改。请参阅以下两种方法。
  • 将新类设置为模型的原型 (setItemPrototype)。

有两种方法可以走得更远:

  1. 从QObject 继承您的项目类,同时从setData 发出信号并在某处订阅每个项目(我不会那样做)。
  2. 将信号itemAboutToChange 添加到QStandardItemModel。

我在 #2 上展开:

  • 创建一个继承自 QStandardItemModel 的新类。
  • 添加宏Q_OBJECT和新信号itemAboutToChange(QStandardItem*)
  • 在派生自QStandardItem 的类的setData 中调用来自模型的信号。

这里是如何调用信号:

 QMetaObject.invokeMethod(self.model(), "itemAboutToChange", Qt::DirectConnection, Q_ARG(QStandardItem*, self));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    相关资源
    最近更新 更多