如何创建带有按钮的新按钮并在 QGraphicSscene 中使用 PyQt5 中的数组绘制它们

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

我有一个应用程序,我在 QGraphicScene 上有几个按钮小部件,我正在尝试使这个按钮小部件在单击时在 QGraphicScene 上创建新按钮。

我的代码如下:

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)

而我的主要class是这样的:

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

如此处所示,我尝试通过单击按钮更新主要 window 中的小部件,但出现 QGraphicsProxyWidget::setWidget: cannot embed widget 0x24ac1a93000; already embedded 错误。

我怎样才能克服这个问题或使这项工作正常的方法是什么?我在这个程序中的主要目标是每个按钮组都可以在单击时创建它们的子按钮组。用 classes 做这个是可行的方法,还是在创建递归小部件时我应该坚持使用 main window class 中的方法?

在此先感谢。

编辑:

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)

SeveralButtons class 不应负责在外部 本身创建新按钮。

您应该发出该信号并将其连接到其父级的函数,然后父级将创建相同 class 的 new 实例并连接信号.

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)