0

There is an interesting issue with Tkinter and threading: I have a Tkinter based GUI and some code executed alongside mainloop. It works like charm if I only do it once. But if i do it twice Tkinter.Tk() blocks BOTH threads: GUI and MainThread.

here is the code (inspired by another Tkinter vs threading topic):

import Tkinter 
import threading
import logging

logging.basicConfig(level=logging.DEBUG, format="%(asctime)s  %(levelname)s: %(message)s")

def gui():
    logging.info("Starting GUI")
    root = Tkinter.Tk() 
    logging.info("Setup GUI")
    root.after(500, root.destroy)
    root.mainloop()
    logging.info("Mainloop is over")

def start_gui_thread():
    gui_thread =  threading.Thread(None, gui, None)
    gui_thread.setDaemon(True)
    gui_thread.start()    
    return gui_thread

def test():
    gui_thread = start_gui_thread()    
    logging.info("Do something alongside gui")

    logging.info("Wait for gui to terminate")
    gui_thread.join()
    logging.info("thread terminated")

logging.info("--------- 1 ---------")
test()
logging.info("--------- 2 ---------")
test()

result: winxp + python 2.7.1 (default installation)

INFO: --------- 1 ---------
INFO: Do something alongside gui
INFO: Starting GUI
INFO: Wait for gui to terminate
INFO: Setup GUI
INFO: Mainloop is over
INFO: thread terminated
INFO: --------- 2 ---------
INFO: Starting GUI
INFO: Do something alongside gui

UPD result with OS X 10.6.7 + python 2.7.1

MacBook-Pro:~ igann$ python test.py 
2012-07-05 21:01:52,939  INFO: --------- 1 ---------
2012-07-05 21:01:52,940  INFO: Starting GUI
2012-07-05 21:01:54,835  INFO: Do something alongside gui
2012-07-05 21:01:54,835  INFO: Wait for gui to terminate
2012-07-05 21:01:54,835  INFO: Setup GUI
2012-07-05 21:01:55,337  INFO: Mainloop is over
2012-07-05 21:01:55,339  INFO: thread terminated
2012-07-05 21:01:55,339  INFO: --------- 2 ---------
2012-07-05 21:01:55,339  INFO: Starting GUI
2012-07-05 21:01:55,366  INFO: Do something alongside gui
2012-07-05 21:01:55,366  INFO: Wait for gui to terminate
2012-07-05 21:01:55,367  INFO: Setup GUI
Tcl_WaitForEvent: CFRunLoop finished
Abort trap
MacBook-Pro:~ igann$ 
Community
  • 1
  • 1
igann
  • 431
  • 4
  • 7
  • 1
    The example misses all the interesting parts, e.g. how you call the UIs methods. You may only do so from the UI thread, not from some other thread, so use a queue.Queue. – schlenk Jul 05 '12 at 15:44
  • This example is just enough for the current issue. – igann Jul 05 '12 at 16:02
  • Offtopic: And you are perfectly right about the most inserting part. I have 2 ways. 1) decorator that turns all the ui-related functions into the root.after() 2) I have Queue for some UI tasks, processed in the UI-thread. – igann Jul 05 '12 at 16:30
  • @schlenk, there is also [mtTkinter](http://tkinter.unpythonic.net/wiki/mtTkinter) that works rather nice (after some modifications). – igann Jul 05 '12 at 19:32
  • Since OS X 10.6.8 comes with Python 2.6.1, I assume that you installed Python 2.7.1 yourself on your OS X 10.6.7? – uselpa Jul 05 '12 at 19:41
  • yes that's right. I tried also with 2.6.1 on the same machine, and i have the same result as before + strange messages listed in your answer. So i have at least 4 independent installations where i can see this bug. I dont think it is an installation problem. – igann Jul 05 '12 at 20:11

1 Answers1

0

It works fine for me (OS X 10.7, Python 2.7.1) so maybe it's related to your installation:

pu@pumbair:~/Downloads$ python test.py 
2012-07-05 19:22:19,673  INFO: --------- 1 ---------
2012-07-05 19:22:19,673  INFO: Starting GUI
2012-07-05 19:22:19,674  INFO: Do something alongside guy
2012-07-05 19:22:19,918  INFO: Wait for gui to terminate
2012-07-05 19:22:19,918  INFO: Setup GUI
2012-07-05 19:22:20,422  INFO: Mainloop is over
2012-07-05 19:22:20,424  INFO: thread terminated
2012-07-05 19:22:20,424  INFO: --------- 2 ---------
2012-07-05 19:22:20,425  INFO: Starting GUI
2012-07-05 19:22:20,459  INFO: Do something alongside gui
2012-07-05 19:22:20,459  INFO: Setup GUI
2012-07-05 19:22:20,459  INFO: Wait for gui to terminate
2012-07-05 19:22:20,962  INFO: Mainloop is over
2012-07-05 19:22:20,965  INFO: thread terminated

pu@pumbair:~/Downloads$ python
Python 2.7.1 (r271:86832, Jun 25 2011, 05:09:01) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

but operations do not always execute in the same order, of course (compare this with above):

pu@pumbair:~/Downloads$ python test.py 
2012-07-05 19:27:17,827  INFO: --------- 1 ---------
2012-07-05 19:27:17,827  INFO: Starting GUI
2012-07-05 19:27:17,827  INFO: Do something alongside gui
2012-07-05 19:27:17,937  INFO: Setup GUI
2012-07-05 19:27:17,938  INFO: Wait for gui to terminate
2012-07-05 19:27:18,440  INFO: Mainloop is over
2012-07-05 19:27:18,442  INFO: thread terminated
2012-07-05 19:27:18,443  INFO: --------- 2 ---------
2012-07-05 19:27:18,443  INFO: Starting GUI
2012-07-05 19:27:18,478  INFO: Do something alongside gui
2012-07-05 19:27:18,478  INFO: Setup GUI
2012-07-05 19:27:18,479  INFO: Wait for gui to terminate
2012-07-05 19:27:18,981  INFO: Mainloop is over
2012-07-05 19:27:18,982  INFO: thread terminated

On 10.6.8 with Python 2.6.1 it also works, but with strange messages:

symacbook:Downloads putest$ python test.py 
2012-07-05 21:33:49,844  INFO: --------- 1 ---------
2012-07-05 21:33:49,844  INFO: Starting GUI
2012-07-05 21:33:49,844  INFO: Do something alongside gui
2012-07-05 21:33:52,356  INFO: Wait for gui to terminate
2012-07-05 21:33:52,356  INFO: Setup GUI
2012-07-05 21:33:52,858  INFO: Mainloop is over
2012-07-05 21:33:52,859  INFO: thread terminated
2012-07-05 21:33:52,860  INFO: --------- 2 ---------
2012-07-05 21:33:52,860  INFO: Starting GUI
2012-07-05 21:33:52,892  INFO: Setup GUI
2012-07-05 21:33:52,892  INFO: Do something alongside gui
2012-07-05 21:33:52,894  INFO: Wait for gui to terminate
2012-07-05 21:33:52.894 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d9d90 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.896 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d51e0 of class NSFont autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.897 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x7fff70737588 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.897 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101233b40 of class _NSThemeCloseWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.898 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e0ef0 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.898 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d51e0 of class NSFont autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.899 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x7fff70737588 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.899 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1170 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.899 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x10120e9c0 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.900 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d51e0 of class NSFont autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.900 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x7fff70737588 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.901 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1710 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.901 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e18e0 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.902 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1012343e0 of class NSTrackingArea autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.902 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101234010 of class NSTrackingArea autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.903 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1910 of class NSView autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.904 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d3550 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.905 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1910 of class NSView autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.905 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101234840 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.906 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1d90 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.906 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101234870 of class __NSFastEnumerationEnumerator autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.907 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101233b40 of class _NSThemeCloseWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.907 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101233b40 of class _NSThemeCloseWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.908 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1710 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.908 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1710 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.908 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1170 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.909 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1170 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.909 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e22e0 of class NSTrackingArea autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.910 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e24d0 of class NSConcreteAttributedString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.911 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x7fff70737588 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.911 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d51e0 of class NSFont autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.911 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002d91f0 of class NSFont autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.912 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x7fff70737588 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.912 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e28b0 of class NSTrackingArea autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.913 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e3ab0 of class NSConcreteMapTable autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.914 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e3e30 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.915 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1dc0 of class NSObject autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.915 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e4120 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.916 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101234a60 of class NSMenuItem autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.916 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002ac2e0 of class NSCFNumber autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.916 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e4180 of class NSCFDictionary autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.917 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x10120e770 of class NSCFNumber autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.917 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1012031d0 of class NSCFDictionary autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.918 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101233b40 of class _NSThemeCloseWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.919 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101233b40 of class _NSThemeCloseWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.919 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1710 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.919 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1710 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.920 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1170 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:52.920 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e1170 of class _NSThemeWidget autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.393 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101236910 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.393 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x10120e770 of class NSCFNumber autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.394 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101236ce0 of class NSCFDictionary autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.394 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002e24b0 of class NSCFString autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.395 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x1002ac2e0 of class NSCFNumber autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.395 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101236d20 of class NSCFDictionary autoreleased with no pool in place - just leaking
2012-07-05 21:33:53.396 Python[1281:3407] *** __NSAutoreleaseNoPool(): Object 0x101236e70 of class NSCFArray autoreleased with no pool in place - just leaking
2012-07-05 21:33:53,398  INFO: Mainloop is over
2012-07-05 21:33:53,400  INFO: thread terminated
uselpa
  • 18,732
  • 2
  • 34
  • 52
  • I tried with 2 more WinXP + Python 2.7.1 with the same result (block on Tkinter.Tk). Then i tried also with OS X 10.6.8 + python 2.7.1 with again the same result. (The order surely can change - multithreading is all about this, isn't it? ))) ) – igann Jul 05 '12 at 19:17
  • Works for me on OS X 10.6.8 as well! – uselpa Jul 05 '12 at 19:42
  • Still doesn't work for me. XP+python2.7.1,XP+python2.7.3 nor OSX10.6.8+python2.6,2.7 – igann Jul 06 '12 at 08:12