我从来没有使用 C++ 遇到过这个问题,但最近我一直在使用 QML/PyQt5/Python 并且遇到了以下错误:
QQmlEngine: Illegal attempt to connect to MyClass(0x1fd42731e50) that is in a different thread than the QML engine QQmlApplicationEngine(0x1fd41562f70.
我有一个工作线程,它创建我定义的QObject。它是由设置为上下文属性的控制器线程生成的。
这是一份 M.R.E.:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 400
height: 600
title: "Clock"
Text {
id: backend_data
anchors.centerIn: parent
text: backend.my_class.value.toString()
}
}
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, QThread, QTimer, pyqtSlot
import sys
import copy
class MyClass(QObject):
value_changed = pyqtSignal()
def __init__(self, value):
QObject.__init__(self)
self._value = value
@pyqtProperty(int, notify=value_changed)
def value(self):
return self._value
class Worker(QObject):
my_class_signal = pyqtSignal(QObject)
def __init__(self, *args, **kwargs):
QObject.__init__(self, *args, **kwargs)
self._i = 0
self.timer=QTimer()
self.timer.timeout.connect(self.send_my_class)
self.timer.start(1000)
self._my_class = MyClass(0)
@pyqtSlot()
def send_my_class(self):
self._i += 1
self._my_class = MyClass(self._i)
self.my_class_signal.emit(self._my_class)
class Backend(QObject):
my_class_changed = pyqtSignal()
def __init__(self, *args, **kwargs):
QObject.__init__(self, *args, **kwargs)
self._my_class = MyClass(0)
self._thread = QThread()
self._worker = Worker()
self._worker.moveToThread(self._thread)
self._worker.my_class_signal.connect(self.receive_my_class)
self._thread.start()
@pyqtSlot(QObject)
def receive_my_class(self, myclass):
self._my_class = myclass
self.my_class_changed.emit()
@pyqtProperty(QObject, notify=my_class_changed)
def my_class(self):
return self._my_class
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
backend = Backend()
engine = QQmlApplicationEngine()
engine.quit.connect(app.quit)
engine.rootContext().setContextProperty('backend', backend)
engine.load('./example.qml')
if len(engine.rootObjects()) > 0:
sys.exit(app.exec())
我应该采取什么不同的做法?