【问题标题】:Removing custom widget from QVBoxLayout从 QVBoxLayout 中删除自定义小部件
【发布时间】:2010-12-24 13:14:41
【问题描述】:

我有一个带有 QVBoxLayout 的 QFrame,我正在将我自己的自定义小部件添加到布局中 模拟 QListWidget 但在项目中有更多信息/功能。我将小部件添加到布局中并在成员变量中保留引用(这是 Python):

 self.sv_widgets[purchase.id] = widget                
 self.vl_seatView.addWidget(widget)

然后,当我完成一个项目时,我想将其从屏幕上删除并清理参考:

self.vl_seatView.removeWidget(self.sv_widgets[purchase.id])
del self.sv_widgets[purchase.id]

不幸的是,小部件仍在屏幕上显示!我已经检查过了,我只将它添加到布局中一次(实际上只显示了一个副本),尝试在布局上手动调用 update(),但无济于事。这样做的正确方法是什么?

【问题讨论】:

    标签: python qt layout pyqt


    【解决方案1】:

    你可以这样做:

    import sip # you'll need this import (no worries, it ships with your pyqt install)
    sip.delete(self.sv_widgets[purchase.id])
    

    sip.delete(obj) 显式 调用相应 C++ 对象的析构函数。 removeWidget 不会导致该析构函数被调用(此时它仍然是 has a parent)并且 del 仅将 Python 对象标记为垃圾回收。

    你可以通过做(适当的清洁)来达到同样的效果:

    self.vl_seatView.removeWidget(self.sv_widgets[purchase.id])
    self.sv_widgets[purchase.id].setParent(None)
    del self.sv_widgets[purchase.id]
    

    【讨论】:

    • 如果我使用它而不是让它被垃圾收集,那确实有效。为什么不直接从布局中删除它从屏幕上删除它?
    • 我已经用解释和另一种实现相同的方法更新了答案。
    • 太好了,我自己永远也想不通,谢谢。
    【解决方案2】:

    你也可以使用 self.sv_widgets[purchase.id].deleteLater()

    【讨论】: