2017-01-20 5 views
2

Der veröffentlichte Code erstellt ein einzelnes Fenster mit 5 Zeilen Widgets. Klicken Sie auf Push Button startet Funktion, die das Fenster nicht von allen Widgets mit .takeAt() Methode löschen. Warum?So löschen Sie Widgets

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_() 

Antwort

1

Erstens Sie nicht sicher können, während iterieren sie Gegenstände aus einem Behälter entfernen. Jedes Mal, wenn Sie ein Element aus dem Layout nehmen, werden alle verbleibenden Elemente nach unten verschoben und ihre Indizes werden entsprechend geändert. Sobald der halbe Wegpunkt überschritten wurde, wird sich Ihr Schleifenzähler nicht mehr auf einen gültigen Gegenstand beziehen. Der richtige Weg, um die Elemente in einer Schleife zu entfernen, ist wie folgt:

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

Zweitens sind die Layout-Elemente, die Sie entfernen sind Layout-Elemente, keine Widgets. Sobald alle Layouts entfernt wurden, bleiben alle Widgets dort, wo sie sind. Sie können dies sehen, wenn Sie die obige Methode verwenden und dann die Größe des Fensters ändern - die Widgets werden nicht mehr von einem Layout verwaltet und daher wird auch ihre Größe nicht geändert.

Wenn Widgets zu einem Layout hinzugefügt werden, werden sie automatisch an das Widget zurückgegeben, das das Layout besitzt. Wenn das übergeordnete Widget gelöscht wird, werden auch alle untergeordneten Elemente rekursiv gelöscht. Also muss ein Widget (oder sein Elternteil) explizit gelöscht werden, damit es vollständig entfernt werden kann:

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

Vielen Dank! Scharf wie immer! – alphanumeric