gpt4 book ai didi

python - PyQt/PySide 中是否需要 deleteLater()?

转载 作者:太空狗 更新时间:2023-10-29 18:00:17 34 4
gpt4 key购买 nike

既然Python中已经有了垃圾收集器,那么在PyQt/PySide中还需要deleteLater()吗?

最佳答案

这取决于你所说的“必要”是什么意思。

如果(例如)在关闭小部件时不小心,应用程序可能可能消耗大量内存。基于 QObject 的类被设计为(可选)在层次结构中链接在一起。当一个顶层对象被删除时,Qt 也会自动删除它的所有子对象。但是,当关闭小部件(QObject 的子类)时,只有在 Qt.WA_DeleteOnClose 出现时才会自动删除。属性已设置(默认情况下通常未设置)。

为了说明,尝试反复打开和关闭此演示脚本中的对话框,并观察全局对象列表如何增长:

import sys
from PyQt5 import QtCore, QtWidgets

class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.checkbox = QtWidgets.QCheckBox('Delete')
self.button = QtWidgets.QPushButton('Open', self)
self.button.clicked.connect(self.openDialog)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.checkbox)
layout.addWidget(self.button)

def openDialog(self):
widget = QtWidgets.QDialog(self)
if (self.checkbox.isChecked() and
not widget.testAttribute(QtCore.Qt.WA_DeleteOnClose)):
widget.setAttribute(QtCore.Qt.WA_DeleteOnClose)
for child in self.findChildren(QtWidgets.QDialog):
if child is not widget:
child.deleteLater()
label = QtWidgets.QLabel(widget)
button = QtWidgets.QPushButton('Close', widget)
button.clicked.connect(widget.close)
layout = QtWidgets.QVBoxLayout(widget)
layout.addWidget(label)
layout.addWidget(button)
objects = self.findChildren(QtCore.QObject)
label.setText('Objects = %d' % len(objects))
print(objects)
widget.show()

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 100, 50)
window.show()
sys.exit(app.exec_())

对于 PyQt/PySide,对象所有权有两个方面:Python 部分和 Qt 部分。通常,删除对对象的最后一个 Python 引用不足以完全清理,因为 Qt 端可能仍然保留着一个引用。

一般来说,Qt 倾向于隐式删除对象。因此,如果您的应用程序创建和删除大量 QObject(或打开和关闭大量 QWidget),如果内存使用是一个问题,您可能需要采取措施显式删除它们。

更新:

只是为了补充上面关于对象所有权的要点。有时,可以保留对对象的 Python 引用,同时 Qt 部分被删除。发生这种情况时,您会看到如下错误:

RuntimeError: underlying C/C++ object has been deleted

通常,Qt 文档会给出一些关于何时可能发生的提示。例如,QAbstractItemView.setModel发出此警告:

The view does not take ownership of the model unless it is the model's parent object...

这是在告诉您,您必须保留对该对象的 Python 引用,或者将合适的父对象传递给该对象的构造函数,因为 Qt 不会总是自动重新设置它的父对象。

关于python - PyQt/PySide 中是否需要 deleteLater()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20164015/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com