如何删除小部件
How to delete widgets
发布的代码创建了一个包含 5 行小部件的 window。
单击 Push Button
会启动 btnClicked
函数,该函数无法使用 .takeAt()
方法从所有小部件中清除 window。为什么?
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_()
首先,您无法在遍历容器时安全地从容器中移除项目。每次你从布局中取出一个项目,剩下的项目都会向下移动,它们的索引也会相应地改变。因此,一旦超过 half-way 点,您的循环计数器将不再引用有效项目。在循环中删除项目的正确方法是这样的:
def btnClicked():
layout = view.layout()
while layout.count():
item = layout.takeAt(0)
print(repr(item))
其次,您要删除的布局项目是 layout-items,而不是小部件。删除所有布局后,所有小部件都将保留在原处。如果您使用上面的方法,然后调整 window 的大小,您可以看到这一点 - 小部件不再由任何布局管理,因此它们也不会调整大小。
将小部件添加到布局后,它们会自动 re-parented 到拥有该布局的小部件。如果删除该父窗口小部件,则其所有子窗口小部件也将被递归删除。因此,必须明确删除小部件(或其父级)才能将其完全删除:
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())
发布的代码创建了一个包含 5 行小部件的 window。
单击 Push Button
会启动 btnClicked
函数,该函数无法使用 .takeAt()
方法从所有小部件中清除 window。为什么?
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_()
首先,您无法在遍历容器时安全地从容器中移除项目。每次你从布局中取出一个项目,剩下的项目都会向下移动,它们的索引也会相应地改变。因此,一旦超过 half-way 点,您的循环计数器将不再引用有效项目。在循环中删除项目的正确方法是这样的:
def btnClicked():
layout = view.layout()
while layout.count():
item = layout.takeAt(0)
print(repr(item))
其次,您要删除的布局项目是 layout-items,而不是小部件。删除所有布局后,所有小部件都将保留在原处。如果您使用上面的方法,然后调整 window 的大小,您可以看到这一点 - 小部件不再由任何布局管理,因此它们也不会调整大小。
将小部件添加到布局后,它们会自动 re-parented 到拥有该布局的小部件。如果删除该父窗口小部件,则其所有子窗口小部件也将被递归删除。因此,必须明确删除小部件(或其父级)才能将其完全删除:
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())