【发布时间】:2016-01-27 10:36:25
【问题描述】:
我正在通过 PySide 使用 Python 和 Qt 编写一个用于数据可视化的 GUI 应用程序。 我偶尔会遇到崩溃('python.exe 已停止工作'),我认为我将其缩小到以下问题:
当从 numpy 数组创建像素图时,即使像素图已经存在,python (?) 也会以某种方式释放内存。 如果使用的图像格式是 QImage.Format_ARGB32,则不会发生这种情况。(为什么不呢?)。查看下面的代码示例,希望您能重现问题。
编辑:澄清 - 如果 numpy 数组没有被 python 删除,一切都按预期工作。但是,在我的应用程序中,新数据不断生成,我必须找到一种好方法来跟踪当前显示为像素图的数据集,并在不再显示时将其删除。我想为 Qt 找到正确的方法来处理(图像)数据并将其存储在内存中,直到不再需要为止。
据我了解Qt和PySide的文档,像素图应该保存图像的所有数据,因此Qt应该负责内存管理。
这是 Qt、Pyside 中的错误,还是我不明白什么?我在常规文档中找不到有关内存管理的任何详细信息。
背景:我需要定期更新要显示的数据,因此在创建像素图和显示它之间,numpy 数据数组可能已经被 python 覆盖(因为涉及一些 CPU 密集型线程,有时会减慢图形用户界面)。因此,永远存储 numpy 数组不是一种选择。
这是一个代码示例,有趣的部分发生在 display_image 方法中:
import numpy as np
from PySide import QtCore, QtGui
import sys
class displaywidget(QtGui.QWidget):
def __init__(self,parent = None):
super(displaywidget, self).__init__(parent)
## set up the GUI elements
self.setLayout(QtGui.QGridLayout())
self.view = QtGui.QGraphicsView()
self.layout().addWidget(self.view)
self.scene = QtGui.QGraphicsScene()
self.view.setScene(self.scene)
# create a pixmap and display it on the graphicsview
self.display_image()
def display_image(self):
# create image data in numpy array
size = 1024
r = np.linspace(0,255, num = size**2, dtype = np.uint32)
argb = (r<<16) +(255<<24)
# image should display a black to red shading
image = QtGui.QImage(argb, size,size, size*4, QtGui.QImage.Format_RGB32)
### using ARGB format option does not cause the problem
# image = QtGui.QImage(argb, size,size, size*4, QtGui.QImage.Format_RGB32)
pixmap = QtGui.QPixmap.fromImage(image)
self.scene.addPixmap(pixmap)
### when the image data is stored, everything works fine, too
# self.cache = argb
### if only the pixmap and image is stored, the problem still exists
# self.cache = [pixmap, image]
def main(argv):
## create application and main window
try:
app = QtGui.QApplication(argv)
new_qtapp = True
except:
new_qtapp = False
mainwindow = QtGui.QMainWindow()
mainwindow.setCentralWidget(displaywidget())
mainwindow.show()
if new_qtapp:
sys.exit(app.exec_())
return mainwindow
if __name__=="__main__":
w = main(sys.argv)
我在通用 Windows7 Office PC 上使用 32 位 Python 2.7.6 和 PySide 1.2.2。
感谢您的帮助!
【问题讨论】:
-
每个“像素”只有一个值。
argb可以重新整形为 (1024, 1024)。您可能需要(1024、1024、3 或 4) -
但它一开始就行不通,不是吗?我很确定 QImage 期望像素值为 32 位值,如 xAARRGGBB
-
是的,你是对的,我的错
-
似乎 QImage 只包含对图像的引用。如果您将
argb存储为类变量,则数据不会被垃圾收集,并且图像将正确显示 -
stackoverflow.com/questions/9794019/… 在此处查看 pwuertz 的答案,了解如何让 PySide 管理内存