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. -
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.
-
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. -
@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 BaseImgWindowwith 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.imganddel self.scaled_imgincloseEvent. 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. -
F feiyuhuahuo has marked this topic as solved on