如何删除小部件

时间:2017-01-20 20:18:28

标签: python pyqt qwidget

发布的代码会创建一个包含5行小部件的单个窗口。 单击Push Button会激活btnClicked功能,该功能无法使用.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 个答案:

答案 0 :(得分: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())