2009-09-30 2 views
4

J'ai une application wxPython (http://www.OpenSTV.org) qui compte les votes en utilisant des méthodes qui ont plusieurs tours. Je voudrais faire deux choses:wxpython - discussions et événements de fenêtre

(1) Pour un grand nombre de bulletins de vote, cela peut être un peu lent, donc je voudrais montrer à l'utilisateur un dialogue de progression afin qu'il ne pense pas que l'application est gelé. (2) Je voudrais autoriser l'utilisateur à rompre les liens manuellement, et cela nécessite que le code de comptage affiche une fenêtre de dialogue.

Pour réaliser (1), je crée un thread pour exécuter le code de comptage, ce qui me permet de présenter une belle boîte de dialogue de progression à l'utilisateur. Le problème avec ceci, cependant, est que le code de comptage n'est pas le thread principal, et seul le thread principal dans wxPython peut traiter des événements de fenêtre.

Je suppose que je pourrais créer un thread pour exécuter la boîte de dialogue de progression à la place, mais cela semble étrange. Existe-t-il une meilleure façon d'accomplir à la fois (1) et (2)?

Répondre

5

Utilisez Queue pour communiquer et synchroniser entre les threads, chaque thread étant «propriétaire» et interagissant exclusivement avec une ressource qui n'est pas pratique à partager.

Dans les toolkits GUI où seul le thread principal peut vraiment gérer l'interface graphique, le thread principal doit jouer - mettre en place et démarrer les threads faisant le travail réel, puis ne fonctionner que GUI, en utilisant Queues pour communiquer et à partir des autres threads. Pour (1), lorsque votre thread de comptage a une mise à jour, il doit le put dans la file d'attente où le thread principal attend; Lorsque votre thread principal reçoit un message approprié sur cette file d'attente, il met à jour la boîte de dialogue de progression. Pour (2), le thread de comptage envoie la requête "avoir l'utilisateur rompu", le thread principal l'obtient et répond de façon appropriée, et renvoie la résolution sur une file d'attente distincte. Donc, en général, il y a deux types de communications: une qui ne nécessite pas de réponse et d'autres qui le nécessitent. Pour le premier type, il suffit de mettre la notification dans la file d'attente appropriée et de continuer tout simplement - il sera pris en compte en temps voulu. Pour ce dernier type, mon idiome préféré est de mettre dans la file d'attente appropriée une paire (request, response_queue). Si autrement les demandes identiques diffèrent en ce que certains ont besoin d'une réponse et d'autres pas, file d'attente (demande, Aucun) lorsqu'aucune réponse n'est nécessaire (et (demande, q) où q est une file d'attente quand une réponse est nécessaire) et l'idiome général, aussi.

3

Il existe plusieurs façons d'appeler le thread principal wxPython à partir d'un thread de processus. Le plus simple est wx.CallAfter() qui exécutera toujours le fonctionnel qui lui est passé dans le thread principal. Vous pouvez également utiliser wx.PostEvent() et il y a un exemple de ceci dans la démo (intitulé: Threads), et il y a plusieurs manières plus compliquées mais plus personnalisables qui sont discutées dans le dernier chapitre de wxPython dans l'action.

+0

Je vois comment cela va me permettre d'exécuter le dialogue de départage dans le thread principal, mais est-ce que l'un ou l'autre permettra au thread principal de communiquer de nouveau avec le thread de comptage? Le thread de comptage doit savoir comment l'utilisateur a rompu l'égalité avant de pouvoir continuer. J'ai peut-être besoin d'une file d'attente pour ça. –

+0

Jeff - À droite, ils communiquent simplement avec le fil principal. – tom10

+0

Quelle que soit la fonction invoquée par wx.CallAfter(), il est également possible d'appeler une méthode ou de modifier directement un attribut dans l'objet thread. – RufusVS

Questions connexes