Source
Important
An object can only be “pushed” to another thread (i.e., the current thread must be the same as the object’s thread), it cannot be “pulled” from an arbitrary thread to the current thread!
pyside6 Q_ARG Q_RETURN_ARG invokeMethod
Source
- an (over-complicated) example that creates an object in the thread of the
RemoteControl
object
class RemoteControl(QObject):
__thread: QThread
def create_object_in_thread(self, object_type: type[_RemoteObjectT], *args, **kwargs) -> _RemoteObjectT:
"""
Create a RemoteObject derived object in the thread where the RemoteControl object lives.
Parameters
----------
object_type : type[_RemoteObjectT]
The type of the object to create
args : Any
Positional arguments for the object constructor
kwargs : Any
Keyword arguments for the object constructor
Returns
-------
_RemoteObjectT
The created object
"""
return self._create_object_in_thread(object_type, args, kwargs)
@Slot("QVariant", "QVariantList", "QVariantMap", result=QObject) # type: ignore[arg-type]
def _create_object_in_thread(self, object_type: type[QObject], args, kwargs) -> QObject:
"""
Helper function to allow calling `create_object_in_thread()` in another thread via `QMetaObject.invokeMethod()`
and correctly map `args` and `kwargs` to the QMetaType system and back.
"""
if QThread.currentThread() != self.__thread:
obj: QObject = QMetaObject.invokeMethod(
self,
"_create_object_in_thread", # type: ignore[arg-type]
Qt.ConnectionType.BlockingQueuedConnection,
Q_RETURN_ARG(QObject),
Q_ARG("QVariant", object_type),
Q_ARG("QVariantList", args),
Q_ARG("QVariantMap", kwargs),
)
return obj
return object_type(*args, **kwargs)
- this is, by the way, way too complicated and can be solved by a much simpler implementation
class RemoteControl(QObject):
__thread: QThread
def create_object_in_thread(self, object_type: type[_RemoteObjectT], *args, **kwargs) -> _RemoteObjectT:
"""
Create a RemoteObject derived object in the thread where the RemoteControl object lives.
Parameters
----------
object_type : type[_RemoteObjectT]
The type of the object to create
args : Any
Positional arguments for the object constructor
kwargs : Any
Keyword arguments for the object constructor
Returns
-------
_RemoteObjectT
The created object
"""
obj = object_type(*args, **kwargs)
obj.moveToThread(self.__thread)
return obj