发出 dataChanged 信号 PyQt5
Posted
技术标签:
【中文标题】发出 dataChanged 信号 PyQt5【英文标题】:emit dataChanged signal PyQt5 【发布时间】:2017-08-20 12:45:29 【问题描述】:我无法从我的模型中发出 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_())
【问题讨论】:
第二种和第三种形式是唯一正确的两种。您显然能够发出信号 - 真正的问题是视图的更新,这可能完全是由其他原因引起的。如需帮助,您应该提供minimal reproducible example。 添加了可验证的示例 在 linux 上使用 python 3.6.2、qt 5.9.1 和 pyqt 5.9 时,您的示例按预期工作。也就是说,如果我在任何窗口中编辑任何颜色,所有其他视图都会立即更新。 ...我犯了一个愚蠢的错误。刚刚再次启动它,它的工作原理。 【参考方案1】:self.dataChanged.emit(index, index, [QtCore.Qt.EditRole])
是正确的。您的代码中的其他地方一定有错误。
【讨论】:
以上是关于发出 dataChanged 信号 PyQt5的主要内容,如果未能解决你的问题,请参考以下文章