在 Pyside 中实现 QQuickAsyncImageProvider;没有这样的信号 QObject::finished()

Implementing QQuickAsyncImageProvider in Pyside; No such signal QObject::finished()

我正在尝试实现 QQuickAsyncImageProvider in Pyside6, referring to the official example. I'm already aware of the potential hurdle that, unlike in the C++ example code, with PySide it's not possible to inherit from both QRunnable and QObject. In order to send a signal from my QRunnable I'm instead using an intermediary QObject, as suggested here 的子类。那部分工作正常。

到目前为止,这是我尝试将这种安排与我自己的 QQuickAsyncImageProvider 子类一起使用:

from PySide6.QtGui import QGuiApplication, QImage
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QObject, QRunnable, QThreadPool, Signal
from PySide6.QtQuick import (QQuickImageResponse, QQuickAsyncImageProvider,
                             QQuickTextureFactory)

class Signaller(QObject):
    done = Signal(QImage)


class AsyncImageResponseRunnable(QRunnable):
    def __init__(self):
        super().__init__()
        self.signaller = Signaller()
        self.done = self.signaller.done

    def run(self):
        image = QImage(400, 400, QImage.Format_RGB32)
        image.fill('red')
        self.done.emit(image)


class AsyncImageResponse(QQuickImageResponse):
    def __init__(self):
        super().__init__()

        runnable = AsyncImageResponseRunnable()
        runnable.done.connect(self.handle_done)
        pool = QThreadPool.globalInstance()
        pool.start(runnable)

    def handle_done(self, image):
        self.image = image
        self.finished.emit()
    
    def textureFactory(self):
        return QQuickTextureFactory.textureFactoryForImage(self.image)


class AsyncImageProvider(QQuickAsyncImageProvider):
    def requestImageResponse(self, image_id, requested_size):
        return AsyncImageResponse()


if __name__ == "__main__":
    app = QGuiApplication()
    engine = QQmlApplicationEngine()
    
    engine.addImageProvider('async_test', AsyncImageProvider())
    
    engine.load('test.qml')
    app.exec()
//test.qml

import QtQuick

Window {
    width: 1200
    height: 800
    visible: true

    Image {
        source: 'image://async_test/test'
    }
}

这会导致分段错误 - 有时,我会立即收到此错误消息:

qt.core.qobject.connect: QObject::connect: No such signal QObject::finished()

乍一看,这似乎与 self.finished.emit() 行有关。然而:

  1. QQuickImageResponse定义了finished信号,
  2. 即使我注释掉 self.finished.emit(),我也收到相同的错误消息,这似乎表明内部必须尝试调用它。

那么,我在这里缺少什么?如何避免分段错误并使我的异步图像提供程序正常运行?

reported this 万一这是一个错误,其中一位维护人员意识到问题是 AsyncImageResponse 被立即删除了。解决方法是在 AsyncImageProvider:

中保留对它的引用
class AsyncImageProvider(QQuickAsyncImageProvider):
    def requestImageResponse(self, image_id, requested_size):
        self.response = AsyncImageResponse()
        return self.response

他们还提出了一个 change 可能会在将来不再需要这样做。