genau, relativ thread safe.
was man zum beispiel nicht machen kann ist es einen Toplevel fenster in einen thread zu erstellen und sein .mainloop im main thread aufzurufen (wann das sinnvoll ist oder nicht spielt keine rolle).
hier ein beispiel:
Code: Alles auswählen
from Tkinter import *
import threading
from time import sleep
SAFE = True
root = Tk()
e = []
if SAFE:
ta = TkThreadAccess(root)
def in_thread():
if SAFE:
top = ta.blocking_do(Toplevel)()
else:
top = Toplevel()
e.append(top)
threading.Thread(target=in_thread).start()
if SAFE:
for i in range(10):
ta.update()
e.pop().mainloop()
TkThreadAccess und dieses beispiel sind nicht optimal implementiert, es geht eher um das prinzip:
statt direkt mit einer funktion an der gui rumzufummeln wird die funktion dem main thread uebergeben, der sie ausfuert und gegebenenfalls das ergebnis dem thread zurueckgeliefert.
in diesen fall haette man bei SAFE = False folgenden fehler
Code: Alles auswählen
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/usr/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "test.py", line 88, in in_thread
top = Toplevel()
File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1978, in __init__
BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1935, in __init__
(widgetName, self._w) + extra + self._options(cnf))
RuntimeError: main thread is not in main loop
(blocking_do sollte besser wrap heissen)