2012-03-28 103 views
17

PySideアプリケーションのレイアウトからQtウィジェットを削除しようとしています。PySide:レイアウトからウィジェットを削除する

ここには最小の例があります。それはそれで5つのボタンを持つウィジェットで、クリックされたとき、真ん中のは自分自身を削除することになっている:

import sys 
from PySide import QtGui 

app = QtGui.QApplication(sys.argv) 
widget = QtGui.QWidget() 
layout = QtGui.QVBoxLayout() 
buttons = [QtGui.QPushButton(str(x)) for x in xrange(5)] 

def deleteButton(): 
    b = layout.takeAt(2) 
    buttons.pop(2) 
    del b 
buttons[2].clicked.connect(deleteButton) 

map(layout.addWidget, buttons) 
widget.setLayout(layout) 
widget.show() 
app.exec_() 

実際に何が起こることはこれです:

What actually happens

ボタンをunclickableと明確ですレイアウト計算には考慮されませんが、そのイメージはそのまま残ります。

Qt documentationによると、レイアウトからすべてのオブジェクトを削除する正しい方法は次のとおりです。

ここ
while ((child = layout->takeAt(0)) != 0) { 
    delete child; 
} 

呼び出すために私は3番目のボタンを削除したいので、私はちょうどtakeAt(2)を呼び出し、その後、del bそのアイテムのデストラクタ。ボタンオブジェクトは、オブジェクトに残っている参照がないことを確認するために、buttonsリストの.popのdです。このような動作を引き起こすQtドキュメントのコードと私のコードはどのように違うのですか?

+5

本当にうまく形成された質問をお祝いしたいと思います。最近私はとても多くのことを見てきましたが、それは文脈のない単純な文章、あるいは私たちが読むと予想される大量のコードです。これには、非常に簡潔で実行可能なコード例とともに、非常に明確な問題が述べられています。あなたの写真は、さらに問題を明確にします。そして、あなたが試したことを示します。ブラボー! – jdi

答えて

28

スーパー簡単な修正:

def deleteButton(): 
    b = layout.takeAt(2) 
    buttons.pop(2) 
    b.widget().deleteLater() 

は、あなたが最初にあなたがレイアウトから返される実際のボタンではなくQWidgetItemに取り組んでいることを確認する必要があり、その後、破壊するためにはQtを教えてくれますdeleteLater()を呼び出しますこのスロットの後のウィジェットは終了し、制御はイベントループに戻ります。

もう1つの例は、問題が発生している理由を示しています。レイアウトアイテムを取得しても、元のレイアウトウィジェットには、元のウィジェットが引き続き親となります。

def deleteButton(): 
    b = layout.takeAt(2) 
    buttons.pop(2) 
    w = b.widget() 
    w.setParent(None) 

これは、オブジェクトのクリーンアップがあいまいであるため、これは推奨されていません。しかしそれは、親をクリアすると視覚的な表示を残すことができることを示しています。しかしdeleteLater()を使用してください。すべてをきれいに整えます。

+0

パーフェクト、ありがとう〜私の髪ももう引っ張られていないので、あなたに感謝します。 –

+0

ハ。そうです。子供が出入りするレイアウトで作業を始めたときも、これで少し気が紛れました。 – jdi

+7

非常に良い答えに追加するだけです。ウィジェットの親が別のウィジェットでなければならず、 'Q * Layout'は' QWidget'から派生していないので、 'Q * Layout'sはウィジェットの' parent'ではありません。彼らは単に親としての移転代理人として働くだけです。レイアウトからウィジェットを削除しても、コンテナウィジェットは親として残り、ボタンはそのままです。 – Avaris

関連する問題