【问题标题】:How to remove all widgets within a QGroupBox in PyQt5?如何在 PyQt5 中删除 QGroupBox 中的所有小部件?
【发布时间】:2019-08-29 18:00:56
【问题描述】:

在我的程序中显示了一个QGroupBox,其中包含许多QPushButton。在程序执行过程中,用户可以点击QGroupBox之外的按钮,其中的所有按钮都将被移除或隐藏。问题是我似乎找不到直接或清除QGroupBox 对按钮执行此操作的方法。

我已经在按钮上尝试了deleteLater,但没有奏效。然后我尝试清除QGroupBoxlayout,但这也不起作用。这是我刚刚写的一些有同样问题的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import random

class UI_Dialog(object):
    def addButtons(self,looping):

        # Code to remove the previous QPushButton's goes here.

        placement = -100
        for i in range(looping):
            currentName = 'btn' + str(i)
            placement = placement + 110
            self.btnB = QtWidgets.QPushButton(self.groupBox)         
            self.btnB.setGeometry(QtCore.QRect(10+placement, 30+placement, 100, 100))
            self.btnB.show()
            self.btnB.setObjectName(currentName)
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(1300, 800)
        self.btnA = QtWidgets.QPushButton(Dialog)
        self.btnA.setGeometry(QtCore.QRect(10, 80, 101, 131))
        self.btnA.setObjectName("btn1")
        self.btnA.clicked.connect(self.pushed)
        self.formLayout = QtWidgets.QFormLayout()
        self.groupBox = QtWidgets.QGroupBox("Results")
        self.groupBox.setLayout(self.formLayout)
        self.resultScrollArea = QtWidgets.QScrollArea(Dialog)
        self.resultScrollArea.setWidget(self.groupBox)
        self.resultScrollArea.setGeometry(QtCore.QRect(20, 220, 1011, 531))
        self.resultScrollArea.setWidgetResizable(True)
        self.resultScrollArea.setObjectName("resultScrollArea")     
        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def pushed(self):
        unkownLength = random.randint(1,20)
        self.addButtons(unkownLength)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Example Program"))
        self.btnA.setText(_translate("Dialog", "Push Button"))

app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = UI_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())

这里有些东西可能没有意义,比如窗口大小、多个函数调用或者它是一个对话框窗口而不是 QMainWindow。但是,在实际程序的上下文中,它们确实有意义,所以忽略它,我知道它效率低下。 unkownLength 变量的全部意义在于模拟在实际程序中,生成的按钮数量将由用户输入决定。按钮也不能在开始时出现,这就是为什么它们是通过单击按钮来创建的。当再次单击该按钮时,它应该删除或隐藏它之前创建的所有按钮。有什么想法吗?

【问题讨论】:

    标签: python-3.x pyqt5 qpushbutton qgroupbox


    【解决方案1】:

    利用按钮是QGroupBox 的子级,我们可以使用findChildren() 获取按钮以使用deleteLater()

    from PyQt5 import QtCore, QtGui, QtWidgets
    import sys
    import random
    
    
    class UI_Dialog(object):
        def setupUi(self, Dialog):
            Dialog.setObjectName("Dialog")
            Dialog.resize(1300, 800)
            self.btnA = QtWidgets.QPushButton(Dialog)
            self.btnA.setGeometry(QtCore.QRect(10, 80, 101, 131))
            self.btnA.setObjectName("btn1")
    
            self.formLayout = QtWidgets.QFormLayout()
            self.groupBox = QtWidgets.QGroupBox("Results")
            self.groupBox.setLayout(self.formLayout)
            self.resultScrollArea = QtWidgets.QScrollArea(Dialog)
            self.resultScrollArea.setWidget(self.groupBox)
            self.resultScrollArea.setGeometry(QtCore.QRect(20, 220, 1011, 531))
            self.resultScrollArea.setWidgetResizable(True)
            self.resultScrollArea.setObjectName("resultScrollArea")
            self.retranslateUi(Dialog)
            QtCore.QMetaObject.connectSlotsByName(Dialog)
    
        def retranslateUi(self, Dialog):
            _translate = QtCore.QCoreApplication.translate
            Dialog.setWindowTitle(_translate("Dialog", "Example Program"))
            self.btnA.setText(_translate("Dialog", "Push Button"))
    
    
    class Dialog(QtWidgets.QDialog, UI_Dialog):
        def __init__(self, parent=None):
            super(Dialog, self).__init__(parent)
            self.setupUi(self)
            self.btnA.clicked.connect(self.pushed)
    
        @QtCore.pyqtSlot()
        def pushed(self):
            unkownLength = random.randint(1, 20)
            self.addButtons(unkownLength)
    
        def addButtons(self, looping):
            for button in self.groupBox.findChildren(QtWidgets.QPushButton):
                button.deleteLater()
            placement = -100
            pos = QtCore.QPoint(20, 40)
            for i in range(looping):
                currentName = "btn" + str(i)
                self.btnB = QtWidgets.QPushButton(
                    self.groupBox, objectName=currentName
                )
                self.btnB.setGeometry(QtCore.QRect(pos, QtCore.QSize(100, 100)))
                pos += QtCore.QPoint(110, 110)
                self.btnB.show()
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        w = Dialog()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】: