Home > Net >  How can I create new buttons with buttons and plot them in QGraphicScene with an array in PyQt5
How can I create new buttons with buttons and plot them in QGraphicScene with an array in PyQt5

Time:05-12

I have an application where I have several button widgets on a QGraphicScene and I am trying to make this button widgets to make new buttons on QGraphicScene when they are clicked.

My code is as follows:

buttons = []

class SeveralButtons(QtWidgets.QWidget):
    def __init__(self,id,x,y):
        super(SeveralButtons,self).__init__()
        self.id = id
        self.x = x
        self.y = y
        self.setGeometry(x,y,1,1)

        self.button1 = QtWidgets.QPushButton("B1")
        self.button2 = QtWidgets.QPushButton("B2")

        self.button1.clicked.connect(self.p1b)

        self.severalButtonsLayout = QtWidgets.QGridLayout()
        self.severalButtonsLayout.addWidget(self.button1, 0,0,)
        self.severalButtonsLayout.addWidget(self.button2, 0,1,)
      
        self.setLayout(self.severalButtonsLayout)

    def p1b(self):
        ph = SeveralButtons(0,self.x-200,self.y-200)
        buttons.append(ph)
        UiWindow._scene.addWidget(ph)

And my main class is like this:

class UiWindow(QtWidgets.QMainWindow):
    factor = 1.5
    def __init__(self, parent=None):
        super(UiWindow, self).__init__(parent)
        self.setFixedSize(940,720)
        self._scene = QtWidgets.QGraphicsScene(self)
        self._view = QtWidgets.QGraphicsView(self._scene)
        self._view.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
        self._view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self._view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        self.initButtons() 
        self.setCentralWidget(self._view)


    def initButtons(self):
        self.p = SeveralButtons(0,500,500)
        buttons.append(self.p)
        self._scene.addWidget(self.p)
        
    
    def updateButtons(self,phrase):
        for b in buttons:
            if b != buttons[0]:
                self._scene.addWidgets(b)
        # ADD BUTTON WIDGET IN buttons ARRAY TO THE _scene OBJECT
        

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ui = UiWindow()
    ui.show()
    sys.exit(app.exec_())

As it is shown in here I am trying to update widgets in main window with button click but I get QGraphicsProxyWidget::setWidget: cannot embed widget 0x24ac1a93000; already embedded error.

How can I overcome this problem or what is the sane way to make this work? My main goal in this program is that every button group can create their children button group when clicked. Doing this with classes is way to go or should I stick to methods in main window class when creating recursive widgets?

Thanks in advance.

EDIT:

class SeveralButtons(QtWidgets.QWidget):
    b1Signal = QtCore.pyqtSignal()
    def __init__():
        self.button1 = QtWidgets.QPushButton()
        self.button1.clicked.connect(self.b1)
        ...
    def b1(self):
        sb = SeveralButtons()
        buttons.append(sb)
        self.b1Signal.emit()


class UiWindow(QtWidgets.QMainWindow):
     def __init__():
         ...
         self.sb1 = SeveralButtons()
         buttons.append(sb1)
         self._scene.addWidget(self.sb1)
         self.sb1.b1Signal.connect(self.updateButtons)
     def updateButtons():
         for b in buttons:
             if b != buttons[0]:
                 self._scene.addWidget(b)

CodePudding user response:

The SeveralButtons class should not be responsible of creating new buttons outside itself.

You should emit that signal and connect it to the function of its parent, which will then create a new instance of the same class and also connect the signal.

class SeveralButtons(QtWidgets.QWidget):
    b1Signal = QtCore.pyqtSignal()
    def __init__():
        super().__init__()
        layout = QtWidgets.QHBoxLayout(self)
        self.button1 = QtWidgets.QPushButton()
        self.button1.clicked.connect(self.b1Signal)
        layout.addWidget(self.button1)


class UiWindow(QtWidgets.QMainWindow):
    def __init__():
        # ...
        self.buttons = []
        self.addButtons()

    def addButtons():
        newButtons = SeveralButtons()
        newButtons.b1Signal.connect(self.addButtons)
        self.buttons.append(newButtons)
        self._scene.addWidget(newButtons)
  • Related