首页 > 解决方案 > 在循环中创建 QPixmap 会占用大量 RAM

问题描述

创建 QPixmap 会使用大量 RAM。

我正在循环创建大约 50 个 QLabel,并将照片添加为封面图像。

这是我正在使用的代码的一小部分基本部分:

def main(self):
    for i in os.listdir(self.directory) * 10:
        image = QLabel(self.labelArea)
    
        image.setPixmap(QPixmap.fromImage(QImage("{}/{}".format(self.directory , i))))
    

假设当前 RAM 为 1400MB。当我运行上述程序时,它会达到 2500MB。这太疯狂了!

第二个代码:

def main():
    for i in os.listdir(self.directory) * 10:
        image = QLabel(self.labelArea)
    
        # image.setPixmap(QPixmap.fromImage(QImage("{}/{}".format(self.directory , i))))

在评论 for 循环的第二行时,RAM 仅达到 1490Mb!(从 1400MB 起)

提供的代码是否有任何问题,或者我在其余代码中搞砸了?

根据要求,最小可重现示例

import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QRect, QSize
from PyQt5.QtGui import QPixmap

def createUi():
    app = QtWidgets.QApplication(sys.argv)
    
    window = QtWidgets.QMainWindow()
    
    imagesArea = QtWidgets.QWidget(window)
    
    window.setCentralWidget(imagesArea)
    
    imagesArea.setGeometry(QRect(0 , 0 , 1980 , 1080))
    
    layout = QtWidgets.QVBoxLayout()
    
    layout.setSpacing(20)
    
    imagesArea.setLayout(layout)
        
    for i in ["sample.jpg"] * 10:
        label = QtWidgets.QLabel()
        
        label.setFixedSize(QSize(400 , 400))
        
        label.setPixmap(QPixmap(i))
        
        label.setScaledContents(True)
        
        layout.addWidget(label)
        
    print("DONE <3")
        
    window.show()
    
    imagesArea.show()
    
    sys.exit(app.exec_())
    
if __name__ == '__main__':
   createUi()

我的目标是在一列中显示所有图像

“my_img.png”的分辨率为 1000x800 像素。

此代码确实使用了 20MB,但最终在 for 循环后下降

如果我谈论 1980x1080 分辨率的图像,仅 10 张图像就需要大约 200 MB!

标签: pythonpython-3.xpyqtpyqt5

解决方案


感谢@musicamante 和@eyllanesc 帮助我找出答案。

我尝试在 PIL 模块的帮助下调整图像大小,我看起来好像在做这个技巧(有点慢,但我会考虑它)

@eyllanesc 发表评论后的回答更新:

更新答案:

import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QRect, QSize
from PyQt5.QtGui import QPixmap
from PIL import Image , ImageQt

def createUi():
    app = QtWidgets.QApplication(sys.argv)
    
    window = QtWidgets.QMainWindow()
    
    imagesArea = QtWidgets.QWidget(window)
    
    window.setCentralWidget(imagesArea)
    
    imagesArea.setGeometry(QRect(0 , 0 , 1980 , 1080))
    
    layout = QtWidgets.QHBoxLayout()
    
    layout.setSpacing(20)
    
    imagesArea.setLayout(layout)
        
    for i in ["sample.jpg"] * 10:
        label = QtWidgets.QLabel()
        
        label.setFixedSize(QSize(400 , 400))
        
        label.setPixmap(QPixmap(i).scaled(400 , 400))
        
        label.setScaledContents(True)
        
        layout.addWidget(label)
                
    window.show()
    
    imagesArea.show()
    
    sys.exit(app.exec_())
    
if __name__ == '__main__':
   createUi()

推荐阅读