PyQT 列表视图未响应数据更改信号 [英] PyQT list view not responding to datachanged signal
问题描述
我一直在学习一些教程并试图建立一个列表模型.我的主窗口有两个访问同一模型的列表视图.当我更新一个列表中的一个项目时,另一个列表在它获得焦点(我点击它)之前不会自我更新.所以看起来 dataChanged 信号没有被发出,但我无法弄清楚我的代码与我所基于的任何示例有何不同.
I've been following some tutorials and trying to get a list model set up. My main window has two list views that are accessing the same model. When I update an item in one list, the other list doesn't update itself until it gets focus (I click on it). So it looks like the dataChanged signal isn't being emitted, but I can't work out how my code is different to any of the examples I'm basing it from.
main.py
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.ui = uic.loadUi("mainwindow.ui", self)
# Test model and listviews
data = [10,20,30,40,50]
myModel = model.MyListModel(data)
self.ui.listView.setModel(myModel)
self.ui.listView_2.setModel(myModel)
model.py
class MyListModel(QtCore.QAbstractListModel):
def __init__(self, data=[], parent=None):
super(MyListModel, self).__init__(parent)
self.__data = data
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.__data)
def data(self, index, role=QtCore.Qt.DisplayRole):
row = index.row()
if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole):
return str(self.__data[row])
if role == QtCore.Qt.ToolTipRole:
return 'Item at {0}'.format(row)
def flags(self, index):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
self.__data[index.row()] = value
self.dataChanged.emit(index, index)
return True
return False
谁能看出这里有什么问题?仅供参考,我使用的是 PyQT5.2.1 和 Python 3.3.
Can anyone see what is wrong here? FYI I'm using PyQT5.2.1 and Python 3.3.
推荐答案
问题在于 dataChanged
信号的签名.在 Qt4 中,它看起来像这样:
The problem is with the signature of dataChanged
signal. In Qt4 it looked like this:
dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight)
但在 Qt5 中,它看起来像这样:
but in Qt5, it looks like this:
dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight,
const QVector<int> & roles = QVector<int>())
当我使用 PyQt-5.1.1 尝试您的示例代码时,尝试在没有第三个参数的情况下发出信号时出现错误.严格来说,这是不正确的行为,因为第三个参数有一个默认值.所以这也许就是行为改变的原因.
when I tried your example code with PyQt-5.1.1, I got an error when attempting to emit the signal without the third argument. Strictly speaking, this was incorrect behaviour, because the third argument has a default value. So this is perhaps why the behaviour has changed.
但似乎您现在必须明确发出一个空列表作为 dataChanged
的第三个参数,以便在 PyQt5 中正常工作:
But it seems that you must now explicitly emit an empty list as the third argument of dataChanged
in order for things to work properly in PyQt5:
self.dataChanged.emit(index, index, [])
或者,当然,发出实际已更改的角色列表:
or, of course, emit a list of the roles that have actually been changed:
self.dataChanged.emit(index, index, [QtCore.Qt.EditRole])
这篇关于PyQT 列表视图未响应数据更改信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!