2009-12-28 15 views
5

Estoy tratando de ejecutar un método en el subproceso de GUI utilizando QMetaObject :: invokeMethod, que devuelve verdadero. Pero, si uso Qt :: QueuedConnection mi método nunca se llama (incluso si invokeMethod devuelve verdadero).QMetaObject :: invokeMethod devuelve verdadero, pero el método nunca se llama

Esto es lo que estoy usando:

QMetaObject::invokeMethod(this, "draw_widgets", Qt::QueuedConnection) 

no recibo ningún mensaje de error ni nada ... Si uso Qt :: Auto Unión o Qt :: DirectConnection el método se consiga llamar , pero desde el mismo hilo, por supuesto. No desde el hilo de la interfaz gráfica de usuario, que es lo que necesito.

draw_widgets es una ranura pública de tipo void draw_widgets() y mi clase hereda QObject y también utiliza la macro Q_OBJECT.

Agradecería cualquier ayuda sobre esto, o sobre cómo comprobar por qué no se está llamando al método.

Gracias.

+0

que tienen una situación similar : Tengo una clase que hereda de QObject y utiliza 'Q_OBJECT'. La instancia de esta clase se crea en el ciclo principal. Luego, al ejecutar un método de la misma clase en el ciclo principal, llamo a 'QMetaObject :: invokeMethod (this," hideListsSlot ", Qt :: QueuedConnection);', donde 'void hideListsSlot()' es un espacio público del clase. La ranura nunca se invoca. – Giorgio

Respuesta

10

El mensaje "verdadero" indica que el mensaje se colocó correctamente. Eso no significa que el mensaje en cola haya sido procesado alguna vez ...

Digamos que su programa tiene 10 hilos (Thread1-Thread10). Pones en cola un mensaje de Thread7. ¿Qué hilo se pondrá en cola? ¿Y cuándo se procesarán los elementos de esta cola?

La respuesta es que cada QObject tiene algo llamado Thread Affinity, y este es el hilo donde se ejecutará una ranura en cola. La afinidad por defecto es el hilo donde se creó el objeto (pero puede cambiar con QObject::moveToThread().)

Si quieres hacer cola algo al hilo de interfaz gráfica de usuario, entonces el objeto especificado por el puntero this debe tener la GUI hilo de afinidad. Puede verificar esto con el método QObject::thread().

Pero en cualquier caso, no importa qué hilo hagas ... debes tener algún tipo de bomba de mensajes ejecutándose en ese hilo. Mire por ejemplo QThread::exec(). Si la afinidad de su hilo es con la GUI, entonces, presumiblemente, este es el caso porque está ejecutando el administrador de la aplicación.

(Como nota al margen, llamadas directas a QMetaObject::invokeMethod son generalmente innecesarios. Puede crear una señal y atarla a una ranura, a continuación, emitir la señal en lugar de la invocación.)

+0

Muchas gracias por su respuesta. No sabía acerca de Thread Affinity. Cambiar la afinidad del objeto por el hilo de la GUI resolvió el problema. –

+0

@HostileFork frente a nota al margen, si tiene demasiadas ranuras, se crearán las mismas señales que las ranuras, por lo que en este caso es justo usar 'QMetaObject :: invokeMethod (this," slot 1 ... n ", Qt :: QueuedConnection) '. –

+0

@HostileFork opuesto a sidenote continue, la llamada 'invokeMethod' debe estar en la ranura dentro de la condición check' if (QThread :: currentThread()! = Thread()) '. de esta manera, los clientes pueden llamar a las máquinas tragamonedas directamente. –

Cuestiones relacionadas