Context
You use the Tkinter mainloop
and a while
-loop and now you want to put both together into one program.
while X:
do_y()
and
master.mainloop()
Solutions
There are several solutions for you.
-
split the loop and use
after
to let the GUI call you back:def do_y2(): do_y() if X: master.after(123, do_y2) # after 123 milli seconds this is called again do_y2() master.mainloop()
For a more detailed answer see this answer by Bryan Oakley
-
use guiLoop by me.
from guiLoop import guiLoop # https://gist.github.com/niccokunzmann/8673951#file-guiloop-py @guiLoop def do_y2(): while X: do_y() yield 0.123 # give the GUI 123 milli seconds to do everything do_y2(master) master.mainloop()
guiLoop uses the approach from 1. but allows you to use one or more while loops.
-
use
update
to refresh the GUI.while X: do_y() master.update()
This approach is an unusual one since it replaces the mainloop that is part os the most GUI frameworks like Tkinter. Note that with 1 and 2 you can have multiple loops, not just one as in 3.
-
use a new thread of execution that executes your loop in parallel. ! This thread must not access master or any GUI elements directly because Tkinter can crash then!
import threading def do_y_loop(): while X: do_y() thread = threading.Thread(target = do_y_loop) thread.deamon = True # use this if your application does not close. thread.start() master.mainloop()
-
start the mainloop in a new thread. As in 4. Tkinter can crash if you access the GUI from the thread.
import threading thread = threading.Thread(target = master.mainloop) thread.deamon = True # use this if your application does not close. thread.start() while X: do_y()
In both 4. and 5. communication between the GUI and the while-loop could/should go through global variables but never through tkinter methods.
For PyQT see these questions: