在 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()
行有关。然而:
QQuickImageResponse
定义了finished
信号,
- 即使我注释掉
self.finished.emit()
,我也收到相同的错误消息,这似乎表明内部必须尝试调用它。
那么,我在这里缺少什么?如何避免分段错误并使我的异步图像提供程序正常运行?
我 reported this 万一这是一个错误,其中一位维护人员意识到问题是 AsyncImageResponse
被立即删除了。解决方法是在 AsyncImageProvider
:
中保留对它的引用
class AsyncImageProvider(QQuickAsyncImageProvider):
def requestImageResponse(self, image_id, requested_size):
self.response = AsyncImageResponse()
return self.response
他们还提出了一个 change 可能会在将来不再需要这样做。
我正在尝试实现 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()
行有关。然而:
QQuickImageResponse
定义了finished
信号,- 即使我注释掉
self.finished.emit()
,我也收到相同的错误消息,这似乎表明内部必须尝试调用它。
那么,我在这里缺少什么?如何避免分段错误并使我的异步图像提供程序正常运行?
我 reported this 万一这是一个错误,其中一位维护人员意识到问题是 AsyncImageResponse
被立即删除了。解决方法是在 AsyncImageProvider
:
class AsyncImageProvider(QQuickAsyncImageProvider):
def requestImageResponse(self, image_id, requested_size):
self.response = AsyncImageResponse()
return self.response
他们还提出了一个 change 可能会在将来不再需要这样做。