max
max

Reputation: 52273

tk: how to invoke it just to display something, and return to the main program?

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

Answers (1)

Bryan Oakley
Bryan Oakley

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

Related Questions