PyQT 列表视图未响应数据更改信号 [英] PyQT list view not responding to datachanged signal

查看:42
本文介绍了PyQT 列表视图未响应数据更改信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习一些教程并试图建立一个列表模型.我的主窗口有两个访问同一模型的列表视图.当我更新一个列表中的一个项目时,另一个列表在它获得焦点(我点击它)之前不会自我更新.所以看起来 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.

ma​​in.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆