我是否需要在PySide2 / Qt中手动销毁对象(例如pixmap)?

问题描述 投票:0回答:1

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

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

从布局中删除小部件widget。通话后,调用方有责任为小部件提供合理的几何形状或将其放回布局中,或在必要时显式隐藏它。

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

python qt user-interface memory-management pyside2
1个回答
0
投票

要了解该操作,您必须具有以下明确的概念:

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

总结:removeWidget()并不用于从布局中删除窗口小部件,而只是使布局不处理该窗口小部件,如果要删除窗口小部件,则必须使用deleteLater()。

from PyQt5 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.deleteLater()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
© www.soinside.com 2019 - 2024. All rights reserved.