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

eud*_*xos 12 python layout qt4 pyqt4

我有一个小部件,当切换选项时,它会发生变化.这会使所有布局和小部件无效.我保留所有布局的列表,所以我可以使用类似于这个答案的东西删除它们:

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.
Run Code Online (Sandbox Code Playgroud)

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


文档非常简洁,显然不能直接应用于python:

QWidget.setLayout(self,QLayout)

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

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

如果此窗口小部件上已安装布局管理器,则QWidget将不允许您安装另一个布局管理器.您必须先删除现有布局管理器(由layout()返回),然后才能使用新布局调用setLayout().

如果layout是不同小部件上的布局管理器,则setLayout()将重新布局布局并使其成为此小部件的布局管理器.

例:

 QVBoxLayout *layout = new QVBoxLayout;
 layout->addWidget(formWidget);
 setLayout(layout);
Run Code Online (Sandbox Code Playgroud)

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

QWidget将获得布局的所有权.

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

ale*_*sdm 28

您只需将布局重新显示为临时窗口小部件:

def reLayout(self):
    QWidget().setLayout(self.layout())
    layout = QGridLayout(self)
    ...
Run Code Online (Sandbox Code Playgroud)

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

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


如果您仍然需要该次要问题的答案:

如何先删除旧布局?

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

QObjectCleanupHandler().add(self.layout())
Run Code Online (Sandbox Code Playgroud)

  • 用于删除布局的`QObjectCleanupHandler()`解决方案的+1. (4认同)