4

我一直在关注一些教程并尝试设置列表模型。我的主窗口有两个访问同一模型的列表视图。当我更新一个列表中的项目时,另一个列表在获得焦点之前不会自行更新(我单击它)。所以看起来 dataChanged 信号没有被发出,但我无法弄清楚我的代码与我所基于的任何示例有何不同。

主文件

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)

模型.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。

4

2 回答 2

8

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])
于 2014-03-21T21:32:32.433 回答
2

解决方案:

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

不适合我(python 2.7,PyQt5)。
但以下其中一项将起作用:

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


self.dataChanged.emit(index, index, list())
于 2016-02-03T00:00:39.527 回答