选择单选按钮之一时动态添加和删除布局

Dynamically add and remove a Layout when one of the Radio Button is Selected

我可以在 pyqt 中为 QHBoxLayout 动态添加布局,但是我无法在添加后删除它们。

主要目的是动态添加和删除基于单选按钮的布局 selected。

def SearchTab(self):

  self.layout = QVBoxLayout()

  button_layout = QHBoxLayout()
  radio_button_1 = QRadioButton("Search")
  radio_button_2 = QRadioButton("Update")
  button_layout.addWidget(radio_button_1)
  button_layout.addWidget(radio_button_2)
  self.layout.addItem(button_layout)

  radio_button_1.toggled.connect(lambda :self.SelectButtonCheck(radio_button_1))
  radio_button_1.toggled.connect(lambda :self.UpdateButtonCheck(radio_button_2))

  self.setTabText(0,"Search")

  self.tab1.setLayout(self.layout)


def SelectButtonCheck(self,b):
    if b.text() == "Search":
        if b.isChecked():
            print(b.text()+ "is selected")
            self.pg_details = pgd.PGDetails()
            layout = self.pg_details.returnLayout()
            self.layout.addLayout(layout)


def UpdateButtonCheck(self,b):

    if b.text() == "Update":
        if b.isChecked():
            print(b.text()+ " is selected")
            for i in  range(self.layout.count()):
                print(self.layout.itemAt(i))
                temp_layout = self.layout.itemAt(i)
                widget = temp_layout.widget()
                temp_layout.removeItem(temp_layout)

                if widget is not None:
                    widget.deleteLater()

初始屏幕-

目前,当 "Search" 单选按钮被 select 编辑时,我可以添加布局 --

但是当我 select "Update" RadioButton

时没有任何反应

同时找到已添加的布局-

for i in  range(self.layout.count()):
print(self.layout.itemAt(i))
<PyQt5.QtWidgets.QHBoxLayout object at 0x1180ec438>
<PyQt5.QtWidgets.QFormLayout object at 0x1180ff828>

正在添加布局,但尚未删除。

任何线索都会有所帮助,我在这里缺少什么

我能够解决这个问题。花了我一段时间,但了解了布局中小部件的排列方式。

我假设删除布局会级联删除小部件本身。

我使用以下函数删除了布局及其对应的小部件。

def SearchTab(self):

      self.layout = QVBoxLayout()

      button_layout = QHBoxLayout()
      radio_button_1 = QRadioButton("Search")
      radio_button_2 = QRadioButton("Update")
      button_layout.addWidget(radio_button_1)
      button_layout.addWidget(radio_button_2)
      self.layout.addItem(button_layout)
      #createDB()
      radio_button_1.toggled.connect(lambda :self.SelectButtonCheck(radio_button_1,self.layout))
      radio_button_1.toggled.connect(lambda :self.UpdateButtonCheck(radio_button_2,self.layout))
      #layout.addRow("Address",QLineEdit())
      self.setTabText(0,"Search")

      update_layout = QHBoxLayout()
      #update_layout.set
      #update_btn = QDialogButtonBox(QDialogButtonBox)
      #update_btn.setAlignment(Qt.AlignBottom)
      update_layout.setAlignment(QtCore.Qt.AlignTop)
      update_btn = QPushButton('Update')
      reset_btn = QPushButton('Reset')
      #self.layout.addRow(update_layout)
      update_layout.addWidget(update_btn)
      update_layout.addWidget(reset_btn)

      update_btn.clicked.connect(self.createDB)

      self.tab1.setLayout(self.layout)

    def SelectButtonCheck(self,b,stacklayout):
        if b.text() == "Search":
            if b.isChecked():
                print(b.text()+ "is selected")
                self.pg_details = pgd.PGDetails()
                layout = self.pg_details.returnLayout()
                self.layout.addLayout(layout)

    def removeLayout(self,layout):
            for i in  range(layout.count()):
                temp_layout = layout.itemAt(i)
                if temp_layout is not None:
                    widget = temp_layout.widget()
                    if widget is not None:
                        widget.deleteLater()
                else:
                    return
                if temp_layout.layout() is not None:
                    self.removeLayout(temp_layout.layout())


    def removeFormLayout(self,layout):

        if layout is not None:

            for i in  range(layout.count()):
                    temp_layout = layout.itemAt(i)
                    if isinstance(temp_layout.layout(),type(QFormLayout())):
                            self.removeLayout(temp_layout.layout())

                    else:
                        next
        else:
            return


    def UpdateButtonCheck(self,b,stacklayout):

        if b.text() == "Update":
            if b.isChecked():
                print(b.text()+ " is selected")
                self.removeFormLayout(stacklayout)

removeFormLayout 函数挑选出我使用“搜索”单选按钮添加的表单布局,removeLayout 也会删除它下面的所有小部件。

对所用方法的建议和改进持开放态度,除了 FormLayout 之外,我还尝试了一些布局删除。目前一切正常。

还有人知道如何在顶部对齐 HBoxLayout 吗,单选按钮又从中间开始,我想在屏幕顶部对齐它们

另一种方法是执行以下操作。 QWidget 和 QGroupBox 有一个 show/hide 选项。

注意,最好总是先躲起来,否则事情会变得不稳定

我有一个具有以下控制逻辑的测试函数

if isOn:
    self.gb1.hide()
    self.gb2.show()
else:
    self.gb2.hide()
    self.gb1.show()

我创建了一个包含上面两个组框的布局。请参阅下面的示例逻辑。我确信有一种方法可以在不将变量存储在 window class.

中的情况下执行此操作
    def create_layout(self):
        ly = QHBoxLayout()
        self.gb1 = self.create_gb_test1()
        self.gb2 = self.create_gb_test2()
        ly.addWidget(self.gb1)
        ly.addWidget(self.gb2)
        return ly

    def create_gb_test1(self):
        my_name = inspect.currentframe().f_code.co_name

        gb = QGroupBox("Find")

        btn_find = QPushButton()

        ly_horiz = QHBoxLayout()
        ly_horiz.addWidget(QLabel("Find:"))
        ly_horiz.addWidget(QLineEdit("Some Text", ))
        ly_horiz.addWidget(btn_find)
        self.ly_find_only = ly_horiz

        gb.setLayout(ly_horiz)
        return gb

    def btn_open_click(self):
        pass

    def create_gb_test2(self):
        my_name = inspect.currentframe().f_code.co_name

        gb = QGroupBox("View")
        btn_open = QPushButton

        cbo = QComboBox()
        cbo.addItems(['a', 'b'])
        ly_horiz = QHBoxLayout()
        ly_horiz.addWidget(QLabel("Find:"))
        ly_horiz.addWidget(cbo)
        ly_horiz.addWidget(btn_open)
        self.ly_find_only = ly_horiz

        gb.setLayout(ly_horiz)
        return gb