Search code examples
pythonqt-designerpyside2

remove a tuggled checkbox from a scroll area when a button is clicked


I am creating a program that has the function that a checkbox is deleted when it toggled. But when I click the delete button it is not deleted from my scroll area.

I have tried some solutions, but I still have problems on it. An the below code is the best condition I managed until now.

# -*- coding: utf-8 -*-

import sys

from PySide2 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(300, 495)
        MainWindow.setMaximumSize(QtCore.QSize(300, 16777215))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.frame_3 = QtWidgets.QFrame(self.centralwidget)
        self.frame_3.setMaximumSize(QtCore.QSize(500, 50))
        self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_3.setObjectName("frame_3")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label = QtWidgets.QLabel(self.frame_3)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        self.verticalLayout.addWidget(self.frame_3)
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.scrollArea = QtWidgets.QScrollArea(self.frame)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 260, 357))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.frame_4 = QtWidgets.QFrame(self.scrollAreaWidgetContents)
        self.frame_4.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_4.setObjectName("frame_4")
        self.verticalLayout_3.addWidget(self.frame_4)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.verticalLayout_2.addWidget(self.scrollArea)
        self.verticalLayout.addWidget(self.frame)
        self.frame_2 = QtWidgets.QFrame(self.centralwidget)
        self.frame_2.setMaximumSize(QtCore.QSize(500, 50))
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_2)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton = QtWidgets.QPushButton(self.frame_2)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QtWidgets.QPushButton(self.frame_2)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        self.verticalLayout.addWidget(self.frame_2)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
        self.label.setText(QtWidgets.QApplication.translate("MainWindow", "Chose Number", None, -1))
        self.pushButton.setText(QtWidgets.QApplication.translate("MainWindow", "add", None, -1))
        self.pushButton_2.setText(QtWidgets.QApplication.translate("MainWindow", "remove", None, -1))


class Remove_checkBox(QtWidgets.QMainWindow,
                      Ui_MainWindow):
    def __init__(self,n):
        super(Remove_checkBox, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.checkBox = []
        self.fill_comboBox(n)

        #Signals
        self.ui.pushButton.clicked.connect(lambda: self.add_param())
        self.ui.pushButton_2.clicked.connect(lambda: self.remove_param())



    def fill_comboBox(self,n):
        self.comboBox = QtWidgets.QComboBox(self.ui.frame_3)
        self.comboBox.addItem("")
        self.comboBox.setItemText(0, QtWidgets.QApplication.translate("MainWindow", "", None, -1))
        self.ui.horizontalLayout_2.addWidget(self.comboBox)
        for i in range(n):
            self.comboBox.addItem("")
            self.comboBox.setItemText(i+1, QtWidgets.QApplication.translate("MainWindow", str(i), None, -1))


    def add_param(self):
        num = self.comboBox.currentText()

        self.checkBox.append(QtWidgets.QCheckBox(self.ui.scrollAreaWidgetContents))
        self.ui.verticalLayout_3.addWidget(self.checkBox[-1])
        self.checkBox[-1].setText(QtWidgets.QApplication.translate("MainWindow", num, None, -1))

        self.ui.verticalLayout_3.removeWidget(self.ui.frame_4)
        self.ui.verticalLayout_3.addWidget(self.ui.frame_4)      

    def remove_param(self):
        for i in range(len(self.checkBox)):
            if self.checkBox[i].isChecked():
                self.ui.verticalLayout_3.removeWidget(self.checkBox[i])
                self.ui.verticalLayout_3.removeWidget(self.ui.frame_4)
                self.ui.verticalLayout_3.addWidget(self.ui.frame_4)      





if __name__ == "__main__":
    n=10
    app = QtWidgets.QApplication.instance()
    if app == None:
        app = QtWidgets.QApplication([])

    myApp = Remove_checkBox(n)

    myApp.show()
    sys.exit(app.exec_())

Solution

  • It took me a while to find a solution that worked with my issue, but I finally arrived to the solution below presented, based on: What is best way to remove items from layout in pyqt

    def remove_element(self, support_layout, element_to_remove, control_list_name):
        """
        This function aims to remove selected elements that  are contained in a
        widget.
    
        Parameters
        ----------
        support_layout : QtWigget Layout
            Layout that supports the object that will be removed
    
        element_to_remove : list with QtWidget 
            A list with Qtwidget items that ones whant to remove.
    
        control_list_name : list with strings
            A list with Qtwidget added items string name
    
        Returns
        -------
        None.
    
        """
        for i in reversed(range(support_layout.count()-1)):
            if element_to_remove[i].isChecked():
                # Remove checkbox from frame
                item = support_layout.takeAt(i)
                widget = item.widget()
                widget.deleteLater()
                # Remove list selected items
                control_list_name.remove(element_to_remove[i].text())
                element_to_remove.remove(element_to_remove[i])
    

    With this function my problem was solved I am able to follow my project.