gpt4 book ai didi

python - 我是否需要手动销毁对象(如像素图)?

转载 作者:行者123 更新时间:2023-12-04 10:04:00 35 4
gpt4 key购买 nike

我正在编写一个基于 PySide2 的应用程序,其中包括一个 QScrollArea有很多QPixmap图像(或更好: QLabel 的列表,这些列表又包含像素图)。随着时间的推移,该图像列表可能会变得非常大,因此当达到一定数量时,我会定期从滚动区域中删除其中一些图像 - 效果很好。

然而,我的印象是,即使删除了一些图像,我的应用程序的内存消耗仍然相同。因此,删除标签小部件可能还不够。来自 QLayout.removeWidget() 上的 PySide2 文档:

Removes the widget widget from the layout. After this call, it is the caller’s responsibility to give the widget a reasonable geometry or to put the widget back into a layout or to explicitly hide it if necessary.



为了删除小部件,我执行以下操作:
while self.images_scroll_layout.count() > MAX_IMAGES:
to_remove = self.images_scroll_layout.itemAt(self.images_scroll_layout.count() - 1)
self.images_scroll_layout.removeItem(to_remove)
to_remove.widget().deleteLater()

所以我的问题是:我是否需要手动销毁从布局中删除的标签/像素图,还是应该自动对它们进行垃圾收集?

最佳答案

要理解操作,您必须有以下清晰的概念:

  • 如果 QObject 有父对象,则 GC 不会删除它。
  • 当一个小部件被添加到布局时,该小部件将被设置为建立布局的小部件的子部件。
  • 当使用 removeWidget() 时,只有小部件会从处理布局的小部件列表中删除,因此小部件的父级仍然是处理布局的小部件。

  • 要验证您可以使用以下代码,其中指示 QObject 何时被删除的销毁信号不会被发出。

    from PySide2 import QtWidgets


    class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
    super().__init__(parent)

    self.add_button = QtWidgets.QPushButton(self.tr("Add"), clicked=self.add_widget)
    self.remove_button = QtWidgets.QPushButton(
    self.tr("Remove"), clicked=self.remove_widget
    )

    scrollarea = QtWidgets.QScrollArea(widgetResizable=True)
    widget = QtWidgets.QWidget()
    scrollarea.setWidget(widget)

    lay = QtWidgets.QVBoxLayout(self)
    lay.addWidget(self.add_button)
    lay.addWidget(self.remove_button)
    lay.addWidget(scrollarea)

    self.resize(640, 480)

    self.label_layouts = QtWidgets.QVBoxLayout(widget)

    self.counter = 0

    def add_widget(self):
    label = QtWidgets.QLabel(f"label {self.counter}")
    self.label_layouts.addWidget(label)
    self.counter += 1

    def remove_widget(self):
    item = self.label_layouts.itemAt(0)
    if item is None:
    return
    widget = item.widget()
    if widget is None:
    return
    widget.destroyed.connect(print)
    print(f"widget: {widget} Parent: {widget.parentWidget()}")


    if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

    总之:removeWidget() 不用于从内存中删除小部件,而只会使布局不处理该小部件,如果要删除小部件,则必须使用 deleteLater()。

    def remove_widget(self):
    item = self.label_layouts.itemAt(0)
    if item is None:
    return
    widget = item.widget()
    if widget is None:
    return
    widget.destroyed.connect(print)
    widget.deleteLater()

    关于python - 我是否需要手动销毁对象(如像素图)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61681200/

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