发出dataChanged信号PyQt5

时间:2017-08-20 12:45:30

标签: pyqt5

我无法从我的模型中发出dataChanged信号。我在python 3.5.2下,PyQt5.9.1。

我尝试了至少4种不同的语法,这些都不适合我:这个模型的不同版本只有在点击它们时才会更新...

@pyqtSlot()
def setData(self, index: QModelIndex, Any, role=None):
    if role == QtCore.Qt.EditRole:
        row = index.row()
        color = QtGui.QColor(Any)
        if color.isValid():
            self._datas[row] = color
            # self.dataChanged.emit(index,index) # doesn't work because PyQt5 changed signature
            # self.dataChanged.emit(index, index, []) # doesn't update other views of the same model
            # self.dataChanged.emit(index,index,[QtCore.Qt.EditRole,]) # neither
            # self.data_changed.emit(index,index) # class method is 'data_changed = pyqtSignal(QModelIndex,QModelIndex)', doesn't work 
            return True
    return False

此问题How to emit dataChanged in PyQt5已标记为已解决,但是,我无法重现

修改 可验证的例子,具有相同模型的多个视图。每当我更改颜色时,我都希望更新所有视图

EDIT_2 解决了...只是一个错字...这个例子按预期工作

from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QModelIndex, pyqtSignal,QAbstractListModel, pyqtSlot
import sys


class listModel(QAbstractListModel):

    def __init__(self, colors=None):
        super(QAbstractListModel, self).__init__()
        self._datas = colors


    def data(self, index: QModelIndex, role=None):
        row = index.row()
        value = self._datas[row]

        if role == QtCore.Qt.DisplayRole:
            return value.name()

        elif role == QtCore.Qt.DecorationRole:
            pixmap = QtGui.QPixmap(12,12)
            pixmap.fill(value)
            icon = QtGui.QPixmap(pixmap)
            return icon

        elif role == QtCore.Qt.ToolTipRole:
            return "Hex code: " + self._datas[row].name()


    def rowCount(self, parent=None, *args, **kwargs):
        return len(self._datas)

    def headerData(self, p_int, Qt_Orientation, role=None):
         if role == QtCore.Qt.DisplayRole:
             if Qt_Orientation == QtCore.Qt.Horizontal:
                 return "Palette"
             else:
                return "Color {a}".format(a=p_int)

    def flags(self, QModelIndex: QModelIndex):
        # check state editable or not?
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled

    @pyqtSlot()
    def setData(self, QModelIndex, Any, role=None):

        if role == QtCore.Qt.EditRole:
            row = QModelIndex.row()
            color = QtGui.QColor(Any)
            if color.isValid():
                self._datas[row] = color
                self.dataChanged.emit(QModelIndex, QModelIndex, [])
                return True
        return False

if __name__ == '__main__':
    app = QApplication(sys.argv)
    red = QtGui.QColor(255,0,0)
    green = QtGui.QColor(0, 255, 0)
    blue = QtGui.QColor(0, 0, 255)
    colors = [red,green,blue]

    model = listModel(colors)

    listView = QtWidgets.QListView()
    listView.setModel(model)
    listView.setWindowTitle('list')
    listView.show()

    treeV = QtWidgets.QTreeView()
    treeV.setModel(model)
    treeV.setWindowTitle('tree')
    treeV.show()

    tableV = QtWidgets.QTableView()
    tableV.setModel(model)
    tableV.setWindowTitle('table')
    tableV.show()


    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:0)

self.dataChanged.emit(index, index, [QtCore.Qt.EditRole])是正确的。您的代码中的其他地方肯定存在错误。