PySide:从布局中删除一个小部件

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (77)

我试图从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)]

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

实际情况是这样的:

该按钮不可点击,显然不考虑布局计算,但其图像保持原位。

根据Qt文档,从布局中删除所有对象的正确方法是:

while ((child = layout->takeAt(0)) != 0) {
    delete child;
}

在这里我只想删除第三个按钮,所以我只是调用takeAt(2),然后del b调用该项目的析构函数。按钮对象也是.popbuttons列表中,以确保没有剩余的对象引用。我的代码与Qt文档中的代码有什么不同,会导致这种行为?

提问于
用户回答回答于

超级简单的修改:

def deleteButton():
    b = layout.takeAt(2)
    buttons.pop(2)
    b.widget().deleteLater()

首先必须确保你正在寻址的是实际的按钮,而不是从布局返回的QWidgetItem,然后调用删除Later(),这将告诉QT在这个插槽结束后销毁小部件,而控制返回到事件循环。

另一个例子说明了问题发生的原因。即使你使用布局项,底层小部件仍然是原始布局小部件的父级。

def deleteButton():
    b = layout.takeAt(2)
    buttons.pop(2)
    w = b.widget()
    w.setParent(None)

扫码关注云+社区