【问题标题】:Pyqt5 refresh/update QListWidget based on event in custom widget?Pyqt5基于自定义小部件中的事件刷新/更新QListWidget?
【发布时间】:2019-05-04 23:44:18
【问题描述】:

单击CustomFormWidget 中的按钮后,我正在尝试更新/刷新 QListWidget。

我想要做的是当我单击CustomFormWidget 中的按钮时,它会更新ParentWid 中的类变量数据,然后重建/更新/刷新ParentWid.ui.listWidget。我应该在哪里以及如何添加这个逻辑。我应该添加到我的CustomFormWidget.on_click 方法还是应该在ParentWid 中设置我的逻辑?

到目前为止,我的代码如下所示:

from PyQt5 import QtCore, QtGui, QtWidgets


class ParentWid(QtWidgets.QDialog):
    data = [
        {
            'id': 1,
            'name': 'pkg-foo',
            'version': '0.1',
            'installed': False
        },
        {
            'id': 2,
            'name': 'pkg-bar',
            'version': '0.1',
            'installed': False
        }
    ]

    def __init__(self, parent=None):
        super(ParentWid, self).__init__(parent)
        self.ui = Ui_ParentWidget()
        self.ui.setupUi(self)
        self.set_widget_data()

    @classmethod
    def update_installed_packages(cls, value):
        for item in ParentWid.data:
            if item["id"] == value:
                item["installed"] = not item["installed"]

    def set_widget_data(self):
        for item in ParentWid.data:
            custFormItem = CustomFormWidget(item)
            lst_item = QtWidgets.QListWidgetItem()
            self.ui.listWidget.insertItem(
                self.ui.listWidget.count(),
                lst_item
            )
            self.ui.listWidget.setItemWidget(lst_item, custFormItem)
            lst_item.setSizeHint(custFormItem.sizeHint())



class CustomFormWidget(QtWidgets.QWidget):
    def __init__(self, data, parent=None):
        super(CustomFormWidget, self).__init__(parent)

        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.data = data

        self.ui.pkg_name.setText(self.data['name'])
        self.ui.pkg_version.setText(self.data['version'])

        if self.data["installed"] is True:
            self.ui.install_btn.setText("Installed")
            self.ui.install_btn.setEnabled(False)

        self.ui.install_btn.clicked.connect(self.on_click)

    def on_click(self):
        print('installed pkg')
        ## install LOGIG
        ParentWid.update_installed_packages(self.data["id"])

【问题讨论】:

    标签: python pyqt pyqt5 qlistwidget


    【解决方案1】:

    在这种情况下,最好让每个项目管理其数据,为此我们可以将 QListWidget 传递给自定义小部件,并在其中通过角色进行处理。在以下示例中,每个小部件都会修改其数据,当应用程序关闭时,会打印更新的数据:

    class Roles:
        IdRole = QtCore.Qt.UserRole + 1000
        NameRole = QtCore.Qt.UserRole + 1001
        VersionRole = QtCore.Qt.UserRole + 1002
        InstalledRole = QtCore.Qt.UserRole + 1003
    
    class ParentWid(QtWidgets.QDialog, Ui_ParentWidget):
        def __init__(self, data={}, parent=None):
            super(ParentWid, self).__init__(parent)
            self.data = data
            self.setupUi(self)
            self.set_widget_data()
    
        def set_widget_data(self):
            for item in self.data:
                lst_item = QtWidgets.QListWidgetItem()
                self.listWidget.addItem(lst_item)
                custFormItem = CustomFormWidget(item, lst_item)
                lst_item.setSizeHint(custFormItem.sizeHint())
    
        def print_results(self):
            v = (("id", Roles.IdRole), ("name", Roles.NameRole), ("version", Roles.VersionRole), ("installed", Roles.InstalledRole),)
            results = []
            for i in range(self.listWidget.count()):
                it = self.listWidget.item(i)
                d = {}
                for k, r in v:
                    d[k] = it.data(r)
                results.append(d)
            print(results)
    
        # test
        def closeEvent(self, event):
            self.print_results()
            super(ParentWid, self).closeEvent(event)
    
    class CustomFormWidget(QtWidgets.QWidget, Ui_Form):
        def __init__(self, data, item, parent=None):
            super(CustomFormWidget, self).__init__(parent)
            self._item = item
            self._item.listWidget().setItemWidget(self._item, self)
            self.setupUi(self)
            v = (("id", Roles.IdRole), ("name", Roles.NameRole), ("version", Roles.VersionRole), ("installed", Roles.InstalledRole),)
            for k, r in v:
                self._item.setData(r, data[k])
            self.update_view()
            self.install_btn.clicked.connect(self.on_click)
    
        def update_view(self):
            self.pkg_name.setText(self._item.data(Roles.NameRole))
            self.pkg_version.setText(self._item.data(Roles.VersionRole))
            v = self._item.data(Roles.InstalledRole)
            self.install_btn.setText("Installed" if v else "Not Installed")
            self.install_btn.setEnabled(not v)
    
        @QtCore.pyqtSlot()
        def on_click(self):
            self._item.setData(Roles.InstalledRole, not self._item.data(Roles.InstalledRole))
            self.update_view()
    
            v = (("id", Roles.IdRole), ("name", Roles.NameRole), ("version", Roles.VersionRole), ("installed", Roles.InstalledRole),)
            for k, r in v:
                print(k, self._item.data(r))
    
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
    
        data = [
            {
                'id': 1,
                'name': 'pkg-foo',
                'version': '0.1',
                'installed': False
            },
            {
                'id': 2,
                'name': 'pkg-bar',
                'version': '0.1',
                'installed': False
            }
        ]
        w = ParentWid(data)
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 有趣的是,当我单击该项目时,如何从CustomFormWidget 打印数据?用于测试目的。
    • 好的,很酷。我想我会改变的一件事是让v 成为一个类变量,因为我们经常使用它。
    猜你喜欢
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 2022-07-02
    • 2014-07-14
    • 2019-04-09
    相关资源
    最近更新 更多