Reputation: 52273
Sorry for the noob question but I really don't understand this.
I'm using python / tkinter and I want to display something (say, a canvas with a few shapes on it), and keep it displayed until the program quits. I understand that no widgets would be displayed until I call tkinter.tk.mainloop()
. However, if I call tkinter.tk.mainloop()
, I won't be able to do anything else until the user closes the main window.
I don't need to monitor any user input events, just display some stuff. What's a good way to do this without giving up control to mainloop
?
EDIT:
Is this sample code reasonable:
class App(tk.Tk):
def __init__(self, sim):
self.sim = sim # link to the simulation instance
self.loop()
def loop():
self.redraw() # update all the GUI to reflect new simulation state
sim.next_step() # advance simulation another step
self.after(0, self.loop)
def redraw():
# get whatever we need from self.sim, and put it on the screen
EDIT2 (added after_idle):
class App(tk.Tk):
def __init__(self, sim):
self.sim = sim # link to the simulation instance
self.after_idle(self.preloop)
def preloop():
self.after(0, self.loop)
def loop():
self.redraw() # update all the GUI to reflect new simulation state
sim.next_step() # advance simulation another step
self.after_idle(self.preloop)
def redraw():
# get whatever we need from self.sim, and put it on the screen
Upvotes: 3
Views: 993
Reputation: 386020
Tk needs an event loop, there's no avoiding that. That's how the widgets know to redraw themselves when obscured, for instance. So, you must have the event loop running.
You have at least three choices. First, use the main thread for the GUI, and put your other logic in a separate thread. A second option is to use two separate processes - one for the GUI, one for your program. Your program can communicate with the GUI over a socket to send it data to display.
Your third option is to learn to live within the event loop. After all, it's really nothing more than a while True
that wraps your whole program. If your main logic runs in a loop, just take out your loop and replace it with the event loop. You can, for example, run one iteration of your code then have it call after
to schedule itself to run again in a few ms. That call to after
adds an event that will call your code whenever the GUI is done with any necessary upkeep.
Upvotes: 3