用另一个布局替换 QWidget 上的布局 [英] replacing layout on a QWidget with another layout

查看:30
本文介绍了用另一个布局替换 QWidget 上的布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小部件,它会在切换选项时发生变化.这将使所有布局和小部件无效.我保留了所有布局的列表,因此我可以使用类似于 this answer 的内容删除它们:

I have a widget which changes when an option is toggled. This invalidates all layouts and widgets. I keep list of all layouts, so I can delete them using something similar to 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.

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

How can I get rid of the old layout and set the new one?

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

The documentation is quite terse and apparently not directly applicable to python:

QWidget.setLayout (self, QLayout)

QWidget.setLayout (self, QLayout)

QLayout 参数已将其所有权转移给 Qt.

The QLayout argument has it's ownership transferred to Qt.

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

Sets the layout manager for this widget to layout.

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

If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.

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

If layout is the layout manger on a different widget, setLayout() will reparent the layout and make it the layout manager for this widget.

示例:

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

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

An alternative to calling this function is to pass this widget to the layout's constructor.

QWidget 将拥有布局的所有权.

The QWidget will take ownership of layout.

另见 layout() 和布局管理.

See also layout() and Layout Management.

推荐答案

您可以简单地将布局重新设置为临时小部件的父级:

You can simply reparent the layout to a temporary widget:

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

这会将所有子窗口小部件重新设置为该临时对象的父对象,并且该对象及其新子对象将立即被删除,因为我们没有保留对它的引用.

That will reparent all the child widgets to that temporary object, and that object is deleted immediately along with its new children because we don't keep a reference to it.

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

But the typical way to have multiple layouts for a single widget and to be able to switch between them is to use a QStackedWidget or QStackedLayout.

<小时>如果您仍然需要第二个问题的答案:


And if you still need the answer to that secondary question:

如何先删除旧布局?

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

It seems you can't delete directly a QObject which has a parent, because the parent is keeping a reference to that object. But you can add the object to a temporary QObjectCleanupHandler which, like the above solution, will be deleted with the object(s) it contains immediately:

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

这篇关于用另一个布局替换 QWidget 上的布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆