2017-01-20 6 views
2

投稿コードは、5行のウィジェットで1つのウィンドウを作成します。 Push Buttonをクリックすると.takeAt()メソッドを使用するすべてのウィジェットからウィンドウをクリアできない関数が起動します。どうして?ウィジェットを削除するには

enter image description here

from PyQt4 import QtCore, QtGui 
app = QtGui.QApplication([]) 

view = QtGui.QWidget() 
view.setLayout(QtGui.QVBoxLayout()) 

def btnClicked(): 
    items = [] 
    for i in range(view.layout().count()): 
     item = view.layout().itemAt(i) 
     items.append(item) 

    for num, item in enumerate(items): 
     print 'taking out item:', num, item 
     view.layout().takeAt(num) 


for i in range(5): 
    sublayout = QtGui.QHBoxLayout() 
    view.layout().addLayout(sublayout) 

    sublayout.addWidget(QtGui.QLabel('Label:')) 
    sublayout.addWidget(QtGui.QLineEdit('Text Edit')) 

    btn = QtGui.QPushButton('Push Button') 
    btn.clicked.connect(btnClicked) 
    sublayout.addWidget(btn) 

view.show() 
app.exec_() 

答えて

1

まず、あなたが安全にそれを反復しながら、コンテナからアイテムを削除することはできません。レイアウトからアイテムを取り出すたびに、残りのアイテムはすべて下に移動し、そのインデックスはそれに従って変更されます。その結果、中間点が通過すると、ループカウンターは有効な項目を参照しなくなります。ループ内の項目を削除する正しい方法は、このようなものです:

def btnClicked(): 
    layout = view.layout() 
    while layout.count(): 
     item = layout.takeAt(0) 
     print(repr(item)) 

第二に、あなたが削除されたレイアウト項目がレイアウトのアイテムではなく、ウィジェットです。すべてのレイアウトが削除されると、すべてのウィジェットがそのまま残されます。上記の方法を使用してウィンドウのサイズを変更すると、これが表示されます。ウィジェットはレイアウトによって管理されなくなり、サイズ変更もされません。

ウィジェットがレイアウトに追加されると、ウィジェットはレイアウトを所有するウィジェットに自動的に再割り当てされます。その親ウィジェットが削除されると、その子ウィジェットもすべて再帰的に削除されます。ウィジェット(またはその親)を完全に削除するには、ウィジェット(またはその親)を明示的に削除する必要があります:

def clearLayout(layout): 
    if layout is not None: 
     while layout.count(): 
      item = layout.takeAt(0) 
      widget = item.widget() 
      if widget is not None: 
       widget.deleteLater() 
      else: 
       clearLayout(item.layout()) 

def btnClicked(): 
    clearLayout(view.layout()) 
+0

ありがとう!いつものようにシャープ! – alphanumeric

関連する問題