PyQT list view not responding to datachanged signal

♀尐吖头ヾ 提交于 2020-01-23 07:51:13

问题


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

Can anyone see what is wrong here? FYI I'm using PyQT5.2.1 and Python 3.3.


回答1:


The problem is with the signature of dataChanged signal. In Qt4 it looked like this:

    dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight)

but in Qt5, it looks like this:

    dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight,
                const QVector<int> & roles = QVector<int>())

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.

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])



回答2:


The solution:

self.dataChanged.emit(index, index, ())

do not work for me (python 2.7, PyQt5).
But one of the following will work:

self.dataChanged.emit(index, index, [])


self.dataChanged.emit(index, index, list())


来源:https://stackoverflow.com/questions/22560296/pyqt-list-view-not-responding-to-datachanged-signal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!