改变前的价值?

时间:2014-09-16 09:03:37

标签: qt pyqt qtablewidget

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

在此更改之前,有没有办法获得更改项目的价值?

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

2 个答案:

答案 0 :(得分:2)

过去参考此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_())

答案 1 :(得分:1)

QStandardItem发生变化时,没有标准方法可以收到通知。但是,您可以轻松实现它:

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

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

  1. 继承QObject的项目类,也可以从setData发出信号并在某处订阅每个项目(我不会这样做)。
  2. 将信号itemAboutToChange添加到QStandardItemModel
  3. 我扩展了#2:

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

    以下是如何调用信号:

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