gpt4 book ai didi

python-3.x - Python3 + Pillow + QT5 : Crash when I resize a label containing an image

转载 作者:行者123 更新时间:2023-12-04 02:09:12 25 4
gpt4 key购买 nike

当我在一个已经可见的窗口中将图像加载到 QLabel 中时,我收到一个消息框:“Python 已停止工作”。选择调试显示:Python.exe 中出现未处理的 Win32 异常。

如果我在显示窗口之前将图像加载到标签中,它会正确显示。

这是精简代码:

#!/usr/bin/etc python
import sys
import os
import stat
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PIL import *
from PIL.ImageQt import *

def update(label):
filename = r"C:\Users\me\Pictures\images\00000229.jpg"
im1 = Image.open(filename)
print ("Read ({},{})".format(im1.width, im1.height))
im2 = im1.rotate(90, expand=True)
print("Rotate ({},{})".format(im2.width, im2.height))

im2.thumbnail((1200,1200))
print("Thumbnail({},{})".format(im2.width, im2.height))

qimage = ImageQt(im2)
pixmap = QPixmap.fromImage(qimage)
label.setPixmap(pixmap)


app = QApplication(sys.argv)

desktop = QDesktopWidget()
deskGeometry = desktop.availableGeometry()
print("desktop ({},{})".format(deskGeometry.width(), deskGeometry.height()))

window = QFrame()
# If you let QT pick the sizes itself, it picks dumb ones, then complains
# 'cause they are dumb
window.setMinimumSize(300, 200)
window.setMaximumSize(deskGeometry.width(), deskGeometry.height())

label = QLabel()
#call update here: no crash

caption = QLabel()
caption.setText("Hello world")

box = QVBoxLayout()
box.addWidget(label)
box.addWidget(caption)
#call update here, no crash
window.setLayout(box)
#call update here, no crash

window.show()
#this call to update results in a crash
update(label)

#window.updateGeometry()
print("App: exec")
app.exec_()

输出:

desktop (3623,2160)
Read (1515,1051)
Rotate (1051,1515)
Thumbnail(832,1200)
App: exec

我是否需要做任何特别的事情来告诉 QT 窗口大小将发生变化?从这里诊断问题的任何建议...


更新:

如果我复制更新函数的主体并将其粘贴到更新调用的位置,它不会长时间崩溃——它会按预期工作。

由此我得出结论,存在对象生命周期问题。 QT 和/或 Pillow 在幕后某处保留指向内部缓冲区的指针,而不是复制或“窃取”缓冲区。当包含缓冲区的对象被删除时,指针变得无效并且“Bad Things Happen[TM]”

现在确定谁在偷懒......

最佳答案

我根据更新中提到的观察结果找到了解决方案,这似乎是一个对象生命周期问题。

更改 update 函数中的行

pixmap = QPixmap.fromImage(qimage)

pixmap = QPixmap.fromImage(qimage).copy()

强制复制像素图。这个副本显然有自己的数据缓冲区,而不是从图像中借用缓冲区。

标签然后保持对像素图的引用——确保缓冲区的生命周期。 “错误”似乎是 QPixmap.fromImage 捕获了指向图像中数据的指针,但没有保留对图像的引用,因此如果图像被垃圾收集(这可能是因为它是一个大对象,标签(和像素图)有一个指向未分配内存的指针。

[这个“指向缓冲区的指针”的东西纯粹是我的猜测,但最重要的是程序不再崩溃。]

关于python-3.x - Python3 + Pillow + QT5 : Crash when I resize a label containing an image,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40356441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com