用另一个布局替换QWidget上的布局

时间:2012-05-02 15:13:03

标签: python layout qt4 pyqt4

我有一个小部件,当切换选项时会更改。这会使所有布局和小部件无效。我保留所有布局的列表,因此我可以使用类似于this answer的内容删除它们:

class MyWidget(QFrame):
   # ...
   def reLayout(self):
      def deleteLayoutChilds(l):
         while l.count():
            item=l.takeAt(0)
            widget=item.widget()
            if widget: widget.deleteLater()
            else: deleteLayoutChilds(item.layout())
      for l in self.allLayouts: deleteLayoutChilds(l)

      # now install the new layout
      ##
      ## how to delete the old layout first?
      l=self.layout(); del l # no effect
      #
      layout=QGridLayout(self)
      ## warning: QLayout: Attempting to add QLayout "" to MyWidget "", which already has a layout.

如何摆脱旧布局并设置新布局?


文档是quite terse,显然不能直接应用于python:

  

QWidget.setLayout(self,QLayout)

     

QLayout论证将其所有权转移到Qt。

     

将此窗口小部件的布局管理器设置为布局。

     

如果此小部件上已安装了布局管理器,则为QWidget   不会让你安装另一个。您必须先删除现有的   布局管理器(由layout()返回),然后才能调用setLayout()   新的布局。

     

如果layout是另一个小部件上的布局管理器,则setLayout()将会   重新布局布局并使其成为此小部件的布局管理器。

     

示例:

 QVBoxLayout *layout = new QVBoxLayout;
 layout->addWidget(formWidget);
 setLayout(layout);
     

调用此函数的另一种方法是将此小部件传递给   布局的构造函数。

     

QWidget将获得布局的所有权。

     

另请参见layout()和布局管理。

1 个答案:

答案 0 :(得分:26)

您可以简单地将布局重新显示为临时窗口小部件:

def reLayout(self):
    QWidget().setLayout(self.layout())
    layout = QGridLayout(self)
    ...

这会将所有子窗口小部件重新显示给该临时对象,并且该对象会立即与其新子节点一起删除,因为我们没有保留对它的引用。

但是,为单个窗口小部件设置多个布局并能够在它们之间切换的典型方法是使用QStackedWidgetQStackedLayout

<小时/> 如果您仍然需要该次要问题的答案:

  

如何先删除旧版面?

您似乎无法直接删除具有父级的QObject,因为父级保留对该对象的引用。但是您可以将对象添加到临时QObjectCleanupHandler,与上述解决方案一样,它将立即与其包含的对象一起删除:

QObjectCleanupHandler().add(self.layout())