Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Widget Addition in PyQt

I'm new to PyQt and I'm trying to create a system which dynamically adds widgets when the user presses add.

I want the same self.comboBox widget to get added above the Add button. I will also make a remove button but I believe that will be no problem.

Moreover, I would like certain checkboxes to appear next to the self.combobox when the user chooses an option (aka option is not -Select-).

Finally, how can I store the user's choices in the checkboxes and the combobox? Do I declare a variable or what exactly?

My code was too much to read, so this instead:

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

like image 278
Osama Adel Avatar asked Mar 06 '23 09:03

Osama Adel


1 Answers

Sorry. If I understand you correctly, your example might look something like this:

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_())        

enter image description here

like image 69
S. Nick Avatar answered Mar 19 '23 19:03

S. Nick