RuntimeError: main thread is not in main loop
When I call
self.client = ThreadedClient()
in my Python program, I get the error
"RuntimeError: main thread is not in main loop"
I have already done some googling, but I am making an error somehow ... Can someone please help me out?
Full error:
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
python multithreading tkinter
add a comment |
When I call
self.client = ThreadedClient()
in my Python program, I get the error
"RuntimeError: main thread is not in main loop"
I have already done some googling, but I am making an error somehow ... Can someone please help me out?
Full error:
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
python multithreading tkinter
From your traceback, it looks like you're running theworkerGuiThreadfrom a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, likeafter).
– Blckknght
Feb 4 '13 at 20:07
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04
add a comment |
When I call
self.client = ThreadedClient()
in my Python program, I get the error
"RuntimeError: main thread is not in main loop"
I have already done some googling, but I am making an error somehow ... Can someone please help me out?
Full error:
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
python multithreading tkinter
When I call
self.client = ThreadedClient()
in my Python program, I get the error
"RuntimeError: main thread is not in main loop"
I have already done some googling, but I am making an error somehow ... Can someone please help me out?
Full error:
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
python multithreading tkinter
python multithreading tkinter
edited Jan 18 '17 at 0:35
Paul Rooney
12.6k72843
12.6k72843
asked Feb 4 '13 at 19:51
user2040823user2040823
91114
91114
From your traceback, it looks like you're running theworkerGuiThreadfrom a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, likeafter).
– Blckknght
Feb 4 '13 at 20:07
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04
add a comment |
From your traceback, it looks like you're running theworkerGuiThreadfrom a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, likeafter).
– Blckknght
Feb 4 '13 at 20:07
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04
From your traceback, it looks like you're running the
workerGuiThread from a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, like after).– Blckknght
Feb 4 '13 at 20:07
From your traceback, it looks like you're running the
workerGuiThread from a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, like after).– Blckknght
Feb 4 '13 at 20:07
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04
add a comment |
2 Answers
2
active
oldest
votes
You're running your main GUI loop in a thread besides the main thread. You cannot do this.
The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it's hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:
Q. Is there an alternative to Tkinter that is thread safe?
Tkinter?
Just run all UI code in the main thread, and let the writers write to a Queue object…
(The sample code given isn't great, but it's enough to figure out what they're suggesting and do things properly.)
There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:
Although Tkinter is technically thread-safe (assuming Tk is built with --enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.
I believe this is exactly what you're seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it's not there.
So, here are some options:
- Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
- If you're using some other library that wants to take over the main thread (e.g.,
twisted), it may have a way to integrate with Tkinter, in which case you should use that. - Use
mkTkinterto solve the problem.
Also, while I didn't find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not callingroot.mainloop()anywhere. Second, you've got methods likedoSomethingthat don't takeself(and aren'tstaticmethods). Third, yourTkinterevent handlers aren't taking aneventparameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.
– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
add a comment |
Since all this did help my problem but did not solve it completely here is an additional thing to keep in mind:
In my case I started off importing the pyplot library in many threads and using it there. After moving all the library calls to my main thread I still got that error.
I did get rid of it by removing all import statements of that library in other files used in other threads. Even if they did not use the library the same error was caused by it.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f14694408%2fruntimeerror-main-thread-is-not-in-main-loop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You're running your main GUI loop in a thread besides the main thread. You cannot do this.
The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it's hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:
Q. Is there an alternative to Tkinter that is thread safe?
Tkinter?
Just run all UI code in the main thread, and let the writers write to a Queue object…
(The sample code given isn't great, but it's enough to figure out what they're suggesting and do things properly.)
There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:
Although Tkinter is technically thread-safe (assuming Tk is built with --enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.
I believe this is exactly what you're seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it's not there.
So, here are some options:
- Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
- If you're using some other library that wants to take over the main thread (e.g.,
twisted), it may have a way to integrate with Tkinter, in which case you should use that. - Use
mkTkinterto solve the problem.
Also, while I didn't find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not callingroot.mainloop()anywhere. Second, you've got methods likedoSomethingthat don't takeself(and aren'tstaticmethods). Third, yourTkinterevent handlers aren't taking aneventparameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.
– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
add a comment |
You're running your main GUI loop in a thread besides the main thread. You cannot do this.
The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it's hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:
Q. Is there an alternative to Tkinter that is thread safe?
Tkinter?
Just run all UI code in the main thread, and let the writers write to a Queue object…
(The sample code given isn't great, but it's enough to figure out what they're suggesting and do things properly.)
There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:
Although Tkinter is technically thread-safe (assuming Tk is built with --enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.
I believe this is exactly what you're seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it's not there.
So, here are some options:
- Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
- If you're using some other library that wants to take over the main thread (e.g.,
twisted), it may have a way to integrate with Tkinter, in which case you should use that. - Use
mkTkinterto solve the problem.
Also, while I didn't find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not callingroot.mainloop()anywhere. Second, you've got methods likedoSomethingthat don't takeself(and aren'tstaticmethods). Third, yourTkinterevent handlers aren't taking aneventparameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.
– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
add a comment |
You're running your main GUI loop in a thread besides the main thread. You cannot do this.
The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it's hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:
Q. Is there an alternative to Tkinter that is thread safe?
Tkinter?
Just run all UI code in the main thread, and let the writers write to a Queue object…
(The sample code given isn't great, but it's enough to figure out what they're suggesting and do things properly.)
There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:
Although Tkinter is technically thread-safe (assuming Tk is built with --enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.
I believe this is exactly what you're seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it's not there.
So, here are some options:
- Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
- If you're using some other library that wants to take over the main thread (e.g.,
twisted), it may have a way to integrate with Tkinter, in which case you should use that. - Use
mkTkinterto solve the problem.
Also, while I didn't find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.
You're running your main GUI loop in a thread besides the main thread. You cannot do this.
The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it's hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:
Q. Is there an alternative to Tkinter that is thread safe?
Tkinter?
Just run all UI code in the main thread, and let the writers write to a Queue object…
(The sample code given isn't great, but it's enough to figure out what they're suggesting and do things properly.)
There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:
Although Tkinter is technically thread-safe (assuming Tk is built with --enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.
I believe this is exactly what you're seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it's not there.
So, here are some options:
- Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
- If you're using some other library that wants to take over the main thread (e.g.,
twisted), it may have a way to integrate with Tkinter, in which case you should use that. - Use
mkTkinterto solve the problem.
Also, while I didn't find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.
edited May 23 '17 at 12:02
Community♦
11
11
answered Feb 4 '13 at 20:26
abarnertabarnert
253k21355460
253k21355460
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not callingroot.mainloop()anywhere. Second, you've got methods likedoSomethingthat don't takeself(and aren'tstaticmethods). Third, yourTkinterevent handlers aren't taking aneventparameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.
– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
add a comment |
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not callingroot.mainloop()anywhere. Second, you've got methods likedoSomethingthat don't takeself(and aren'tstaticmethods). Third, yourTkinterevent handlers aren't taking aneventparameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.
– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
Hey abarnert. Thanks for your answer. I have used for the option with mtTkinter. My code is running (without errors I mean). But I can't see the canvas ... In the logging I see the program is working ... only without visualisation. You can't see the code @ github.com/wimhendrickx/Flocking/blob/master/bird_swarm.py. Thanks in advance.
– user2040823
Feb 5 '13 at 20:46
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: Why can't I see the code, is it in white text on a white background? :) Anyway, I'll download it and take a look.
– abarnert
Feb 5 '13 at 20:53
@user2040823: OK, there are multiple elementary problems here. First, you're not calling
root.mainloop() anywhere. Second, you've got methods like doSomething that don't take self (and aren't staticmethods). Third, your Tkinter event handlers aren't taking an event parameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.– abarnert
Feb 5 '13 at 21:05
@user2040823: OK, there are multiple elementary problems here. First, you're not calling
root.mainloop() anywhere. Second, you've got methods like doSomething that don't take self (and aren't staticmethods). Third, your Tkinter event handlers aren't taking an event parameter. I think you need to work through a basic Tkinter tutorial before you try to build something complicated around it and/or use mtTkinter. If you have any specific questions that you can't find answers to, create a new question, but I can't teach you Tkinter basics in SO comments.– abarnert
Feb 5 '13 at 21:05
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
Hey again. Thx for looking at my code. At the moment I am only using my canvas for output (the button is not working). I just want to visualize the birds in the swarm. But I shall take your advice and build a small sub project!
– user2040823
Feb 5 '13 at 21:28
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
As a note to myself and anybody interested: there is a problem when you don't use queue for GUI events and instead just call object methods from non-main thread, the code might work on Linux but fail on Windows. Or probably work on py3.6 and fail on py3.5...
– MarSoft
Feb 10 '17 at 3:35
add a comment |
Since all this did help my problem but did not solve it completely here is an additional thing to keep in mind:
In my case I started off importing the pyplot library in many threads and using it there. After moving all the library calls to my main thread I still got that error.
I did get rid of it by removing all import statements of that library in other files used in other threads. Even if they did not use the library the same error was caused by it.
add a comment |
Since all this did help my problem but did not solve it completely here is an additional thing to keep in mind:
In my case I started off importing the pyplot library in many threads and using it there. After moving all the library calls to my main thread I still got that error.
I did get rid of it by removing all import statements of that library in other files used in other threads. Even if they did not use the library the same error was caused by it.
add a comment |
Since all this did help my problem but did not solve it completely here is an additional thing to keep in mind:
In my case I started off importing the pyplot library in many threads and using it there. After moving all the library calls to my main thread I still got that error.
I did get rid of it by removing all import statements of that library in other files used in other threads. Even if they did not use the library the same error was caused by it.
Since all this did help my problem but did not solve it completely here is an additional thing to keep in mind:
In my case I started off importing the pyplot library in many threads and using it there. After moving all the library calls to my main thread I still got that error.
I did get rid of it by removing all import statements of that library in other files used in other threads. Even if they did not use the library the same error was caused by it.
answered Dec 30 '18 at 23:24
Christian MoszChristian Mosz
24318
24318
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f14694408%2fruntimeerror-main-thread-is-not-in-main-loop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
From your traceback, it looks like you're running the
workerGuiThreadfrom a thread you're creating elsewhere, rather from the main thread of execution. I'm not a TK expert, but the error seems to suggest that this is not allowed (you need to use the main thread to call the TK functions, likeafter).– Blckknght
Feb 4 '13 at 20:07
See this question, this answer, etc. for some details on using TkInter in a multithreaded program. But the short version is: Only use it in the main thread, period.
– abarnert
Feb 4 '13 at 20:23
Hey Blckknght. Therefor I am using mtTkinter.
– user2040823
Feb 5 '13 at 21:04