Memory leak after closing window
-
from PySide6.QtWidgets import QVBoxLayout, QPushButton, QWidget from PySide6.QtUiTools import QUiLoader from PySide6.QtWidgets import QApplication, QLabel, QMainWindow from PySide6.QtCore import Qt, QPoint, QPointF, QRect, QObject from PySide6.QtGui import QPixmap, QPainter class BaseImgFrame(QLabel): def __init__(self, parent=None): super().__init__(parent) self.painter = QPainter() self.resize(512, 512) self.img, self.scaled_img = None, None self.img_tl = QPointF(0., 0.) # 图片左上角在控件坐标系的坐标 self.interpolation = Qt.FastTransformation def closeEvent(self, event): self.deleteLater() event.accept() def paintEvent(self, e): self.painter.begin(self) self.painter.drawPixmap(self.img_tl, self.scaled_img) self.painter.end() def paint_img(self, img_path_or_pix_map): self.img = QPixmap(img_path_or_pix_map) self.scaled_img = self.img.scaled(self.size(), Qt.KeepAspectRatio, self.interpolation) self.update() class BaseImgWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) loader = QUiLoader() loader.registerCustomWidget(BaseImgFrame) self.ui = loader.load('ui_files/base_img_window.ui') self.setCentralWidget(self.ui) self.resize(512, 512) def closeEvent(self, event): self.deleteLater() event.accept() def paint_img(self, img_path_or_pix_map): self.ui.img_area.paint_img(img_path_or_pix_map) class ImageDisplay(QMainWindow): def __init__(self): super().__init__() self.central_widget = QWidget(self) self.setCentralWidget(self.central_widget) lay = QVBoxLayout(self.central_widget) self.button = QPushButton(self) lay.addWidget(self.button) self.central_widget.setLayout(lay) self.button.clicked.connect(self.add) def add(self): window_new_img = BaseImgWindow(self) window_new_img.setAttribute(Qt.WA_DeleteOnClose) window_new_img.paint_img(QPixmap('D:\Data\yyyy\原图/8.10.jpg')) window_new_img.show() if __name__ == '__main__': app = QApplication() window = ImageDisplay() window.show() app.exec()
Click the button, a new window will show. But the memory does not release correctly after closing the window (Better test with a large image). The ui file is here: https://github.com/feiyuhuahuo/HuaHuoLabel/blob/new_fw/ui_files/base_img_window.ui
The PySide6 version is 6.5.2 and OS is Windows11. -
@feiyuhuahuo It is up to the OS when the memory is really released. Closing a window does not necessary mean that its memory is immediately released. If you really want to find out whether there is a memory leak you should open and close that window many times and look at the memory consumption.
-
@feiyuhuahuo @jsulm is right. You can make a loop to create and destroy the window a few times and check if the memory leak problem stays. Never used python. Do you need to clear self.img after it is scaled to self.scaled_img?
-
@jsulm Hi, I hope that the memory can be released after the window is closed. So I add such code:
window_new_img.setAttribute(Qt.WA_DeleteOnClose)
. But it doesn't. I test with a large image, and ~75M memory is occupied every time I show a new window. Only ~2M memory is released every time I close a window. I find it's aboutregisterCustomWidget
. If I replaceclass BaseImgWindow
with code:class BaseImgWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = QMainWindow(self) layout = QVBoxLayout(self.ui) self.ui.setLayout(layout) self.label = BaseImgFrame(self) layout.addWidget(self.label) self.setCentralWidget(self.ui) self.resize(512, 512) def closeEvent(self, event): self.deleteLater() event.accept() def paint_img(self, img_path_or_pix_map): self.label.paint_img(img_path_or_pix_map)
Then the memory can be correctly released. Confused why there's such a difference.
@JoeCFD I add codedel self.img
anddel self.scaled_img
incloseEvent
. But that just doesn't work. -
@feiyuhuahuo said in Memory leak after closing window:
The PySide6 version is 6.5.2 and OS is Windows11.
Hi @jsulm @JoeCFD , seems I have to use pyside6-uic to convert my ui file to python code to avoid this problem. But still, I found another memory bug: https://forum.qt.io/topic/152101/memory-can-not-release-correctly-because-of-using-lambda-as-slot
Thanks a lot for the help. -