2009-12-28 8 views
5

J'essaie d'exécuter une méthode sur le thread graphique en utilisant QMetaObject :: invokeMethod, qui renvoie true. Mais, si j'utilise Qt :: QueuedConnection, ma méthode n'est jamais appelée (même si invokeMethod renvoie true).QMetaObject :: invokeMethod renvoie la valeur true, mais la méthode n'est jamais appelée

C'est ce que j'utilise:

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

Je ne reçois aucun message d'erreur ou quoi que ce soit ... Si j'utilise Qt :: AutoConnection ou Qt :: DirectConnection la méthode ne soit appelée , mais du même fil bien sûr. Pas du fil de l'interface graphique, ce dont j'ai besoin. Draw_widgets est un espace public de type void draw_widgets() et ma classe hérite de QObject et utilise également la macro Q_OBJECT.

J'apprécierais toute aide à ce sujet, ou sur la façon de vérifier pourquoi la méthode n'est pas appelée.

Merci.

+0

J'ai une situation similaire : J'ai une classe qui hérite de QObject et utilise 'Q_OBJECT'. L'instance de cette classe est créée dans la boucle principale. Ensuite, lors de l'exécution d'une méthode de la même classe dans la boucle principale, j'appelle 'QMetaObject :: invokeMethod (this," hideListsSlot ", Qt :: QueuedConnection);', où 'void hideListsSlot()' est un emplacement public de la classe. L'emplacement n'est jamais invoqué. – Giorgio

Répondre

10

Le «vrai» vous indique que le message a été mis en file d'attente avec succès. Cela ne signifie pas que le message en file d'attente a été traité ...

Disons que votre programme a 10 threads (Thread1-Thread10). Vous mettez en file d'attente un message à partir de Thread7. Quel fil sera-t-il mis en file d'attente? Et quand les articles de cette file seront-ils traités?

La réponse est que chaque QObject a quelque chose appelé Thread Affinity, et c'est le thread où un slot en file d'attente sera exécuté. L'affinité par défaut est le thread dans lequel l'objet a été créé (mais vous pouvez le changer avec QObject::moveToThread().)

Si vous voulez faire la queue quelque chose au fil de l'interface graphique, l'objet spécifié par votre pointeur this devrait avoir de fil GUI affinité. Vous pouvez vérifier ceci avec la méthode QObject::thread().

Mais dans tous les cas, quel que soit le fil que vous mettez en file d'attente ... vous devez avoir une sorte de pompe de messages s'exécutant sur ce fil. Regardez par exemple QThread::exec(). Si votre affinité de thread est à l'interface graphique, alors c'est probablement déjà le cas parce que vous exécutez l'exec de l'application.

(En sidenote, les appels directs à QMetaObject::invokeMethod sont généralement vous pouvez inutiles. Créer un signal et l'attacher à une fente, émettre le signal au lieu du Invoke.)

+0

Merci beaucoup pour votre réponse. Je ne connaissais pas Thread Affinity. Changer l'affinité de l'objet pour le thread graphique a résolu le problème. –

+0

@HostileFork sidenote, si vous avez trop de slots, il sera créé des signaux comme les slots, donc dans ce cas, il est juste d'utiliser 'QMetaObject :: invokeMethod (this," slot 1 ... n ", Qt :: QueuedConnection) '. –

+0

@HostileFork opposé sidenote continuer, l'appel 'invokeMethod' devrait être palced dans l'emplacement à l'intérieur de la condition vérifier' if (QThread :: currentThread()! = Thread()) '. De cette façon, les clients peuvent appeler les slots directement. –

Questions connexes