J'ai un script python qui utilise tkinter pour l'interface graphique. Mon petit script devrait créer un widget de toplevel toutes les x secondes. Lorsque j'exécute mon code, le premier widget Toplevel est créé avec succès, mais lorsqu'il essaie de créer une seconde, le programme se bloque.
Ce que je fais est à l'aide de la méthode après appel à la fonction d'ouverture de la fonction toutes les 5 secondes aux côtés de la ligne principale de la racine. Chaque fois que cette fonction est appelée, j'ai appellé un objet de widget de Toplevel dans une liste et démarrez un nouveau fil qui, espérons-le, exécutera le nouveau Mainloop. P>
Je serais très reconnaissant si quelqu'un pouvait comprendre ce problème. Au fait, c'est juste un petit script que j'utilise actuellement pour résoudre mon problème, ce qui m'empêche d'aller avec mon projet d'école réel. P>
Le code: P>
import threading,thread from Tkinter import * def startCounting(): global root global topLevelList global classInstance topLevelList.append (Toplevel()) topLevelList[len(topLevelList)-1].title("Child") classInstance.append(mainLoopThread(topLevelList[len(topLevelList)-1])) root.after(5000,startCounting) class mainLoopThread(threading.Thread): def __init__(self,toplevelW): self.toplevelW = toplevelW threading.Thread.__init__(self) self.start() def run(self): self.toplevelW.mainloop() global classInstance classInstance = [] global topLevelList topLevelList = [] global root root = Tk() root.title("Main") startCounting() root.mainloop()
3 Réponses :
Tkinter est conçu pour fonctionner à partir du fil principal, uniquement. Voir The Docs : P>
Il suffit d'exécuter tout le code de l'interface utilisateur dans la principale fil, et laissez les écrivains écrire à un Objet de la file d'attente; E.g. p> blockQuote>
... et un exemple substantiel suit, montrant des threads secondaires écrivant des demandes à une file d'attente et la boucle principale étant exclusivement responsable de toutes les interactions directes avec TK. P>
De nombreux objets et sous-systèmes n'affucent pas à recevoir des demandes de plusieurs threads divers et, dans le cas de la boîte à outils de l'interface graphique, il n'est pas rare d'avoir besoin spécifiquement d'utiliser le fil fort> strict>. p>
La bonne architecture de Python de ce numéro est toujours de consacrer un fil (le principal, s'il faut) à servir l'objet ou le sous-système finiky; Tous les autres threads nécessitant une interaction avec ledit sous-système ou objet doivent les obtenir en file d'attente en file d'attente sur le thread dédié (et éventuellement attendre sur une "file d'attente de retour" pour les résultats, si des résultats sont nécessaires à la suite d'une certaine demande). C'est également une architecture python très sienne pour un filetage à usage général (et je l'expose longuement dans "Python en un mot", mais c'est un autre sujet; -). P>
J'ai rencontré cette restriction et c'est exactement la tactique que j'utilise. J'ai une méthode qui vérifie toutes les files d'attente. J'inscrit ensuite cette méthode avec la boucle principale de Tkinter en appelant root.Après (MS, My_Method). Le dernier appel de My_Method est un autre appel à root.Après de sorte que my_method perturment continuellement avec la boucle principale. Il est important que des exceptions dans My_Method ne vous empêchent pas de vous inscrire avec le Mainloop. Vous voudrez peut-être mettre votre appel à root.Après dans la partie enfin d'essayer / enfin.
Y a-t-il une raison pour laquelle vous voulez (ou pensez-vous besoin de besoin) une boucle d'événement par la fenêtre TOPLEVEL? Une seule boucle d'événement est capable de gérer des dizaines (sinon centaines ou des milliers) de fenêtres de toplevel. Et, comme cela a été signalé dans une autre réponse, vous ne pouvez pas exécuter cette boucle d'événement dans un fil séparé. P>
Donc, pour corriger votre code, vous devez utiliser uniquement une seule boucle d'événement et faire fonctionner dans le fil principal. p>
Merci beaucoup pour les réponses, j'ai pu résoudre le problème grâce à vos gars, je n'avais jamais posté dans un endroit comme celui-ci et j'ai été agréablement surpris de tellement d'aide.
Tkinter a des problèmes liés à la saisie à partir de threads multiples, j'utilise Mttkinter à la place, vous n'aurez pas besoin de changer de code et tout fonctionnera bien. Il suffit d'importer mttkinter au lieu de tkinter. P>
Vous pouvez l'obtenir ici: P>