Python PySide:从布局中删除小部件
我正在尝试从PySide应用程序的布局中删除Qt小部件 这里是一个最小的例子。这是一个有5个按钮的小部件,中间的按钮应该在单击时自动删除:Python PySide:从布局中删除小部件,python,qt,pyside,qlayout,Python,Qt,Pyside,Qlayout,我正在尝试从PySide应用程序的布局中删除Qt小部件 这里是一个最小的例子。这是一个有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
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_()
实际情况是:
按钮是不可点击的,显然在布局计算中没有考虑到,但其图像保持不变
根据,从布局中删除所有对象的正确方法是:
while ((child = layout->takeAt(0)) != 0) {
delete child;
}
这里我只想删除第三个按钮,所以我只需调用takeAt(2)
,然后delb
调用该项的析构函数。按钮对象也是从按钮列表中弹出的,以确保没有对对象的剩余引用。我的代码与Qt文档中可能导致这种行为的代码有何不同?超级简单修复:
def deleteButton():
b = layout.takeAt(2)
buttons.pop(2)
b.widget().deleteLater()
您首先必须确保寻址的是实际的按钮,而不是从布局返回的QWidgetItem,然后调用deleteLater(),这将告诉Qt在该插槽结束后销毁小部件,并将控件返回到事件循环
另一个例子说明了问题发生的原因。即使您使用布局项,底层小部件仍然是原始布局小部件的父级
def deleteButton():
b = layout.takeAt(2)
buttons.pop(2)
w = b.widget()
w.setParent(None)
这不是首选方法,因为它仍然使对象的清理不明确。但它表明,清除父项允许它离开可视显示。不过,请使用
deleteLater()
。它能很好地清理一切。我只想祝贺你提出了一个非常有条理的问题。我最近看到了很多,只是一些没有上下文的句子,或者是我们期望阅读的大量代码。这说明了一个非常明确的问题,以及一个非常简洁且可运行的代码示例。你的照片也进一步澄清了这个问题。你要展示你所尝试过的。好极了!太好了,谢谢~我的头发也谢谢你,因为它不再被扯了。哈。是的,当我第一次开始处理有孩子来来去去去的布局时,我也被这一点咬了一口。我要补充一个非常好的答案:Q*Layout
s从来都不是小部件的父项,因为小部件的父项必须是另一个小部件,Q*Layout
不是从QWidget
派生出来的。他们只是作为父母身份的转移代理。即使您从布局中删除了小部件,容器小部件仍然是父部件,并且您的按钮仍然存在。