简体   繁体   English

为什么我需要将 QBuffer 分配给一个变量,以免 QImageReader 崩溃?

[英]Why do I need to assign QBuffer to a variable in order not to crash QImageReader?

That's such a weird bug, if it's even a bug.这是一个如此奇怪的错误,如果它甚至是一个错误的话。

This works:这有效:

from PySide6.QtCore import QBuffer, QByteArray, QFile, QIODevice

from PySide6.QtGui import QImageReader


image_path = Path('/home/p10/testIAMAGAGADS.png')
file = QFile(image_path)
file.open(QIODevice.ReadOnly)
blob = file.readAll()
buffer = QBuffer(blob)
image_reader = QImageReader(buffer)

This crashes PySide6:这会使 PySide6 崩溃:

from pathlib import Path
from PySide6.QtCore import QBuffer, QByteArray, QFile, QIODevice

from PySide6.QtGui import QImageReader


image_path = Path('/home/p10/testIAMAGAGADS.png')
file = QFile(image_path)
file.open(QIODevice.ReadOnly)
blob = file.readAll()
image_reader = QImageReader(QBuffer(blob))

I would expect an object created in a specific scope (albeit passed as an argument) to stay alive at least till the end of that scope.我希望在特定的 scope(尽管作为参数传递)中创建的 object 至少在 scope 结束之前保持活动状态。 PS: The same thing happens when I read the image from a file to a bytes object and pass it to QBuffer without binding it to a variable beforehand. PS:当我将图像从文件读取到字节 object 并将其传递给 QBuffer 而不事先将其绑定到变量时,也会发生同样的事情。

There's no bug or weirdness here.这里没有错误或怪异。 The second example does not keep a reference to the QBuffer object, so it gets garbage-collected (by Python).第二个示例没有保留对 QBuffer object 的引用,因此它被垃圾收集(通过 Python)。 This is no different than doing eg len(dict(a=1)) : the dict will be deleted immediately after len returns.这与例如len(dict(a=1))没有什么不同:在len返回后,dict 将立即被删除。 The image reader takes a pointer to a QIODEvice.图像阅读器采用指向 QIODEvice 的指针。 If it tries to read from that device (via the pointer) after it's been deleted, a fatal error will occur.如果它在被删除后尝试从该设备(通过指针)读取,则会发生致命错误。

The Qt docs will usually explicitly state whether ownership passes to the receiver, and there's no indication that QImageReader will do this. Qt 文档通常会明确 state 所有权是否传递给接收者,并且没有迹象表明QImageReader会这样做。 In fact, the docs include the following:事实上,这些文档包括以下内容:

Note : QImageReader assumes exclusive control over the file or device that is assigned.注意:QImageReader 假定对分配的文件或设备具有独占控制权。 Any attempts to modify the assigned file or device during the lifetime of the QImageReader object will yield undefined results.在 QImageReader object 的生命周期内修改分配的文件或设备的任何尝试都将产生未定义的结果。

One way to fix the second example would be to make the QBuffer a child of the QFile (since they both inherit QObject):修复第二个示例的一种方法是使 QBuffer 成为 QFile 的子项(因为它们都继承了 QObject):

from pathlib import Path
from PySide6.QtCore import QBuffer, QByteArray, QFile, QIODevice
from PySide6.QtGui import QImageReader

image_path = Path('/home/p10/testIAMAGAGADS.png')
file = QFile(image_path)
file.open(QIODevice.OpenModeFlag.ReadOnly)
blob = file.readAll()
image_reader = QImageReader(QBuffer(blob, file))
image = image_reader.read()
print(image)

(NB: when the QFile is deleted, Qt will automatically delete all its children as well). (注意:当 QFile 被删除时,Qt 也会自动删除它的所有子文件)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM