RuntimeError: main thread is not in main loop












18















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









share|improve this question

























  • 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













  • Hey Blckknght. Therefor I am using mtTkinter.

    – user2040823
    Feb 5 '13 at 21:04
















18















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









share|improve this question

























  • 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













  • Hey Blckknght. Therefor I am using mtTkinter.

    – user2040823
    Feb 5 '13 at 21:04














18












18








18


3






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









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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













  • 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











  • 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












2 Answers
2






active

oldest

votes


















25














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 mkTkinter to 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.






share|improve this answer


























  • 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 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











  • 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



















0














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.






share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    25














    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 mkTkinter to 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.






    share|improve this answer


























    • 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 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











    • 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
















    25














    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 mkTkinter to 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.






    share|improve this answer


























    • 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 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











    • 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














    25












    25








    25







    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 mkTkinter to 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.






    share|improve this answer















    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 mkTkinter to 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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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











    • 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













    • @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











    • 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













    0














    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.






    share|improve this answer




























      0














      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.






      share|improve this answer


























        0












        0








        0







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 30 '18 at 23:24









        Christian MoszChristian Mosz

        24318




        24318






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Mossoró

            Error while reading .h5 file using the rhdf5 package in R

            Pushsharp Apns notification error: 'InvalidToken'