RuntimeError: thread principal n'est pas dans la boucle principale
Quand je l'appelle
self.client = ThreadedClient()
dans mon programme en Python, j'obtiens l'erreur
"RuntimeError: thread principal n'est pas dans la boucle principale"
J'ai déjà fait quelques recherches sur google, mais je fais une erreur quelque sorte ... quelqu'un Peut-il m'aider?
D'erreur complet:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 530, in __bootstrap_inner
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 483, in run
File "/Users/Wim/Bird Swarm/bird_swarm.py", line 156, in workerGuiThread
self.root.after(200, self.workerGuiThread)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 501, in after
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1098, in _register
RuntimeError: main thread is not in main loop
Classes:
class ThreadedClient(object):
def __init__(self):
self.queue = Queue.Queue( )
self.gui = GuiPart(self.queue, self.endApplication)
self.root = self.gui.getRoot()
self.running = True
self.GuiThread = threading.Thread(target=self.workerGuiThread)
self.GuiThread.start()
def workerGuiThread(self):
while self.running:
self.root.after(200, self.workerGuiThread)
self.gui.processIncoming( )
def endApplication(self):
self.running = False
def tc_TekenVogel(self,vogel):
self.queue.put(vogel)
class GuiPart(object):
def __init__(self, queue, endCommand):
self.queue = queue
self.root = Tkinter.Tk()
Tkinter.Canvas(self.root,width=g_groottescherm,height=g_groottescherm).pack()
Tkinter.Button(self.root, text="Move 1 tick", command=self.doSomething).pack()
self.vogelcords = {} #register of bird and their corresponding coordinates
def getRoot(self):
return self.root
def doSomething():
pass #button action
def processIncoming(self):
while self.queue.qsize( ):
try:
msg = self.queue.get(0)
try:
vogel = msg
l = vogel.geeflocatie()
if self.vogelcords.has_key(vogel):
cirkel = self.vogelcords[vogel]
self.gcanvas.coords(cirkel,l.geefx()-g_groottevogel,l.geefy()-g_groottevogel,l.geefx()+g_groottevogel,l.geefy()+g_groottevogel)
else:
cirkel = self.gcanvas.create_oval(l.geefx()-g_groottevogel,l.geefy()-g_groottevogel,l.geefx()+g_groottevogel,l.geefy()+g_groottevogel,fill='red',outline='black',width=1)
self.vogelcords[vogel] = cirkel
self.gcanvas.update()
except:
print('Failed, was van het type %' % type(msg))
except Queue.Empty:
pass
À partir de votre traceback, on dirait que vous êtes l'exécution de la
Voir cette question, cette réponse, etc. pour plus de détails sur l'utilisation de TkInter dans un programme multithread. Mais la version courte est: à utiliser Uniquement dans le thread principal, période.
Hey Blckknght. À cet effet, je suis en utilisant mtTkinter.
workerGuiThread
à partir d'un thread que vous êtes la création d'ailleurs, au lieu de le thread principal d'exécution. Je ne suis pas un TK expert, mais l'erreur semble suggérer que ce n'est pas autorisé (vous devez utiliser le thread principal pour appeler les SAVOIRS traditionnels fonctions, comme after
).Voir cette question, cette réponse, etc. pour plus de détails sur l'utilisation de TkInter dans un programme multithread. Mais la version courte est: à utiliser Uniquement dans le thread principal, période.
Hey Blckknght. À cet effet, je suis en utilisant mtTkinter.
OriginalL'auteur user2040823 | 2013-02-04
Vous devez vous connecter pour publier un commentaire.
Vous êtes en cours d'exécution de votre interface graphique principale de la boucle dans un thread d'ailleurs le thread principal. Vous ne pouvez pas faire cela.
Les docs mention offhandedly dans quelques endroits que Tkinter n'est pas thread-safe, mais autant que je sache, jamais tout à fait de sortir et de dire que vous ne pouvez parler de Savoirs traditionnels du thread principal. La raison en est que la vérité est un peu compliqué. Tkinter, lui-même est thread-safe, mais il est difficile à utiliser dans un multithread. La plus proche à la documentation officielle sur ce qui semble être cette page:
(L'exemple de code donné n'est pas grand, mais il suffit de comprendre ce qu'ils sont en train de suggérer et de faire les choses correctement.)
En fait, il y est un thread-safe alternative à Tkinter, mtTkinter. Et ses docs en fait expliquer assez bien la situation:
Je crois que c'est exactement ce que vous voyez: votre Tkinter code Thread 1 est d'essayer de regarder dans le thread principal pour trouver la boucle principale, et il n'est pas là.
Alors, voici quelques options:
twisted
), il peut avoir un moyen de s'intégrer avec Tkinter, dans ce cas, vous devriez l'utiliser.mkTkinter
pour résoudre le problème.Aussi, bien que je n'ai pas trouver toutes les doublons exacts de cette question, il y a un certain nombre de questions connexes. Voir cette question, cette réponse, et beaucoup plus pour plus d'informations.
Pourquoi ne puis-je pas voir le code, est-il dans un texte blanc sur un fond blanc? 🙂 De toute façon, je vais le télécharger et de regarder.
OK, il y a plusieurs élémentaire des problèmes ici. Tout d'abord, vous n'êtes pas à l'appel de
root.mainloop()
n'importe où. Deuxièmement, vous avez des méthodes commedoSomething
qui ne prennent pasself
(et ne sont passtaticmethod
s). Troisièmement, votreTkinter
gestionnaires d'événements ne sont pas de prendre unevent
paramètre. Je pense que vous avez besoin de travailler à travers une base de Tkinter le tutoriel avant de vous essayer de construire quelque chose de compliqué autour d'elle et/ou de l'utilisation mtTkinter. Si vous avez des questions spécifiques que vous ne pouvez pas trouver des réponses, et de créer une nouvelle question, mais je ne peux pas vous enseigner Tkinter notions de base dans les commentaires.Hey encore une fois. Merci de regarder mon code. Pour le moment je n'en suis qu'à l'aide de ma toile pour la sortie (le bouton ne fonctionne pas). Je veux juste visualiser les oiseaux dans l'essaim. Mais je vais prendre vos conseils et de construire un petit sous de projet de!
Comme une note à moi-même et tous ceux qui sont intéressés: il y a un problème lorsque vous n'utilisez pas de file d'attente de l'interface événements et, au lieu de simplement appeler les méthodes d'objet non thread principal, le code peut fonctionner sur Linux, mais ne parviennent pas sur Windows. Ou probablement travailler sur py3.6 et échouent sur les py3.5...
OriginalL'auteur abarnert