Intento ilegal de conectar a una variable que se encuentra en un hilo diferente al del motor QML.
He creado un objeto (que hereda de QObject) en mi main.cpp y estoy pasando este objeto a otro hilo. Para simplificar las cosas, mi main se ve así:
main.cpp
QGuiApplication app(argc, argv);
ClientListWrapper clients; // Hereda de QObject
if (!clients.initialize())
return -1;
args2thread->Pointer2clients = &clients; // Pasando este objeto al hilo
std::thread Listening_thread(thread_function, args2thread); // Creando un hilo
Ahora en mi función de hilo estoy modificando el objeto clients, es decir:
myThread.cpp
// Recibir datos del cliente aquí
.
args2thread->clients->addClient(data); // Almacenar los datos recibidos
.
QT responde con los siguientes errores en tiempo de ejecución:
QObject: No se pueden crear hijos para un padre que está en un hilo diferente.
QQmlEngine: Intento ilegal de conectarse a Client(0x11198860) que está en un hilo diferente al motor QML QQmlApplicationEngine.
davy.ai
El mensaje de error indica que no podemos realizar cambios en un QObject que fue creado en un hilo desde otro hilo. En este caso, el objeto
ClientListWrapper
fue creado en el hilo principal y se pasó alListening_thread
. Cuandothread_function
intenta modificar el objetoClientListWrapper
, lo está haciendo desde un hilo diferente, lo que causa errores en tiempo de ejecución.Para solucionar este problema, debemos asegurarnos de que todas las modificaciones al objeto
ClientListWrapper
se realicen desde el mismo hilo que lo creó. Una forma de lograr esto es usar la claseQThread
de Qt en lugar destd::thread
. Podemos crear una subclase deQThread
y mover el objetoClientListWrapper
al nuevo hilo utilizandoQObject::moveToThread()
:En esta solución, creamos un objeto
ListeningThread
que toma un puntero al objetoClientListWrapper
. Luego llamamos amoveToThread()
para mover el objetoClientListWrapper
al nuevo hilo. Finalmente, llamamos astart()
para iniciar el hilo.En el método
run()
deListeningThread
, ahora podemos realizar modificaciones de forma segura en el objetoClientListWrapper
utilizandoQMetaObject::invokeMethod()
con el parámetroAutoConnection
. Esto garantiza que la llamada al método se ejecute en el contexto del nuevo hilo.Usar
QThread
ymoveToThread()
es una forma más sencilla y compatible con Qt de manejar el multihilo en las aplicaciones de Qt. Nos permite evitar problemas comunes, como modificar QObjects desde múltiples hilos.