Pyqt5 根据自定义小部件中的事件刷新/更新 QListWidget? [英] Pyqt5 refresh/update QListWidget based on event in custom widget?
问题描述
在单击 CustomFormWidget
中的按钮后,我试图更新/刷新 QListWidget.
I am trying to update/refresh a QListWidget after I click a button in a CustomFormWidget
.
我想要做的是当我单击 CustomFormWidget
中的按钮时,它会更新 ParentWid
中的类变量数据,然后重建/更新/刷新 <代码>ParentWid.ui.listWidget.我应该在哪里以及如何添加这个逻辑.我应该添加到我的 CustomFormWidget.on_click
方法还是应该在 ParentWid
中设置我的逻辑?
What I am trying to do is when I click the button in a CustomFormWidget
, it updates the class variable data in the ParentWid
and then rebuilds/updated/refreshes ParentWid.ui.listWidget
. Where and how should I add this logic. Should I add to my CustomFormWidget.on_click
method or should my logic be set in the ParentWid
?
到目前为止我的代码看起来像:
So far my code looks like:
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"])
推荐答案
在这种情况下,每个项目最好管理其数据,为此我们可以将 QListWidget 传递给自定义小部件并在其中通过角色处理.在以下示例中,每个小部件都会修改其数据,并在关闭应用程序时打印更新的数据:
In this case it is better that each item manages its data, for this we can pass the QListWidget to the custom widget and in it handle through roles. In the following example, each widget modifies its data, and when the application is closed, the updated data is printed:
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_())
这篇关于Pyqt5 根据自定义小部件中的事件刷新/更新 QListWidget?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!