Pyqt5 обновить / обновить QListWidget на основе события в пользовательском виджете? - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь обновить / обновить QListWidget после нажатия кнопки в CustomFormWidget.

Я пытаюсь сделать следующее: когда я нажимаю кнопку в 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"])

1 Ответ

0 голосов
/ 03 декабря 2018

В этом случае лучше, чтобы каждый элемент управлял своими данными, для этого мы можем передать 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_())
...