18

オプションを切り替えると変化するウィジェットがあります。これにより、すべてのレイアウトとウィジェットが無効になります。すべてのレイアウトのリストを保持しているので、この回答に似たものを使用してそれらを削除できます:

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.

古いレイアウトを削除して新しいレイアウトを設定するにはどうすればよいですか?


ドキュメントは非常に簡潔で、Python には直接適用できないようです。

QWidget.setLayout (自己、QLayout)

QLayout 引数の所有権は Qt に譲渡されます。

このウィジェットのレイアウト マネージャーをレイアウトに設定します。

このウィジェットに既にレイアウト マネージャーがインストールされている場合、QWidget は別のインストールを許可しません。新しいレイアウトで setLayout() を呼び出す前に、まず既存のレイアウト マネージャー (layout() によって返される) を削除する必要があります。

layout が別のウィジェットのレイアウト マネージャーである場合、setLayout() はレイアウトの親を変更し、このウィジェットのレイアウト マネージャーにします。

例:

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

この関数を呼び出す代わりに、このウィジェットをレイアウトのコンストラクターに渡すこともできます。

QWidget はレイアウトの所有権を取得します。

layout() およびレイアウト管理も参照してください。

4

1 に答える 1

37

レイアウトの親を一時ウィジェットに変更するだけです。

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

これにより、すべての子ウィジェットの親がその一時オブジェクトに変更され、そのオブジェクトへの参照が保持されないため、そのオブジェクトは新しい子と共にすぐに削除されます。

しかし、1 つのウィジェットに複数のレイアウトを用意し、それらを切り替えることができる一般的な方法は、QStackedWidgetまたはを使用することQStackedLayoutです。


そして、その二次的な質問に対する答えがまだ必要な場合:

最初に古いレイアウトを削除するには?

QObject親がそのオブジェクトへの参照を保持しているため、親を持つ a を直接削除できないようです。ただし、オブジェクトを一時的に追加することはできます。QObjectCleanupHandlerこれは、上記のソリューションのように、含まれているオブジェクトと共にすぐに削除されます。

QObjectCleanupHandler().add(self.layout())
于 2012-05-03T20:56:41.420 に答える