PyQt 中的动态小部件添加

Posted

技术标签:

【中文标题】PyQt 中的动态小部件添加【英文标题】:Dynamic Widget Addition in PyQt 【发布时间】:2018-09-18 15:17:07 【问题描述】:

我是 PyQt 的新手,我正在尝试创建一个在用户按下添加时动态添加小部件的系统。

我希望将相同的 self.comboBox 小部件添加到上方添加按钮。我也会做一个删除按钮,但我相信这不会有问题。

此外,当用户选择一个选项(又名选项不是-Select-)时,我希望某些复选框出现在 self.combobox 旁边。

最后,如何将用户的选择存储在复选框和组合框中?我是声明一个变量还是究竟是什么?

我的代码太难读了,所以改为:

class myWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.init()
        self.organize()

    def init(self):
        self.label = QLabel("Label")
        self.comboBox = QComboBox(self)
        self.comboBox.addItem("-Select-")
        self.comboBox.addItem("1")
        self.comboBox.addItem("2")
        self.comboBox.addItem("3")
        self.addbtn = QPushButton("Add")
        self.addbtn.clicked.connect(self.addComboBox)

    def organize(self):
        grid = QGridLayout(self)
        self.setLayout(grid)

        grid.addWidget(Label, 0, 0, 0, 2)
        grid.addWidget(self.comboBox, 1, 2, 1, 3)
        grid.addWidget(self.addbtn, 2, 2)

    def addComboBox(self):
        #Code to add a combo box just like self.comboBox above addbtn and below all existing comboBoxes.

What I want

【问题讨论】:

提供minimal reproducible example 我编辑了帖子@eyllanesc 你可以解释你想得到什么,也许一些图片可以帮助你了解自己。 【参考方案1】:

对不起。如果我理解正确,您的示例可能如下所示:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class CheckableComboBox(QComboBox):
    def __init__(self, parent = None):
        super(CheckableComboBox, self).__init__(parent)
        self.parent = parent
        self.setView(QListView(self))
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QStandardItemModel(self))

    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.checkState() == Qt.Checked:
            item.setCheckState(Qt.Unchecked)
        else:
            item.setCheckState(Qt.Checked)
        self.on_selectedItems()    

    def checkedItems(self):
        checkedItems = []
        for index in range(self.count()):
            item = self.model().item(index)
            if item.checkState() == Qt.Checked:
                checkedItems.append(item)
        return checkedItems

    def on_selectedItems(self):
        selectedItems = self.checkedItems()
        self.parent.lblSelectItem.setText("")
        for item in selectedItems:  
            self.parent.lblSelectItem.setText("  "
                       "".format(self.parent.lblSelectItem.text(), item.text()))


class ExampleWidget(QGroupBox):
    def __init__(self, numAddWidget):
        QGroupBox.__init__(self)
        self.numAddWidget = numAddWidget
        self.numAddItem   = 1
        self.setTitle("Title ".format(self.numAddWidget)) 
        self.initSubject()
        self.organize()

    def initSubject(self):
        self.lblName = QLabel("Label Title ".format(self.numAddWidget), self)
        self.lblSelectItem = QLabel(self)

        self.teachersselect = CheckableComboBox(self)
        self.teachersselect.addItem("-Select -".format(self.numAddItem))
        item = self.teachersselect.model().item(0, 0)
        item.setCheckState(Qt.Unchecked)

        self.addbtn = QPushButton("ComboBoxAddItem...", self)
        self.addbtn.clicked.connect(self.addTeacher)

    def organize(self):
        grid = QGridLayout(self)
        self.setLayout(grid)
        grid.addWidget(self.lblName,        0, 0, 1, 3)
        grid.addWidget(self.lblSelectItem,  1, 0, 1, 2)
        grid.addWidget(self.teachersselect, 1, 2)
        grid.addWidget(self.addbtn,         3, 2)

    def addTeacher(self):
        self.numAddItem += 1
        self.teachersselect.addItem("-Select -".format(self.numAddItem))
        item = self.teachersselect.model().item(self.numAddItem-1, 0)
        item.setCheckState(Qt.Unchecked) 


class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.numAddWidget = 1
        self.initUi()

    def initUi(self):
        self.layoutV = QVBoxLayout(self)

        self.area = QScrollArea(self)
        self.area.setWidgetResizable(True)
        self.scrollAreaWidgetContents = QWidget()
        self.scrollAreaWidgetContents.setGeometry(0, 0, 200, 100)

        self.layoutH = QHBoxLayout(self.scrollAreaWidgetContents)
        self.gridLayout = QGridLayout()
        self.layoutH.addLayout(self.gridLayout)

        self.area.setWidget(self.scrollAreaWidgetContents)
        self.add_button = QPushButton("Add Widget")
        self.layoutV.addWidget(self.area)
        self.layoutV.addWidget(self.add_button)
        self.add_button.clicked.connect(self.addWidget)

        self.widget = ExampleWidget(self.numAddWidget)
        self.gridLayout.addWidget(self.widget)
        self.setGeometry(700, 200, 350, 300)        

    def addWidget(self):
        self.numAddWidget += 1
        self.widget = ExampleWidget(self.numAddWidget)
        self.gridLayout.addWidget(self.widget)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyApp()
    w.show()
    sys.exit(app.exec_())        

【讨论】:

这不是我想要的,但实际上它是我想要的更好的版本。

以上是关于PyQt 中的动态小部件添加的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 - 动态添加小部件到布局

访问动态添加的小部件 (pyqt)

通过 pyqt5 动态添加和删除小部件

Pyqt5 addStretch 在小部件之间?

PyQt4 - 自定义小部件类结构?

将 MouseDoubleClickEvent 添加到 PyQt5 中的 for 循环中制作的小部件 [重复]