tk: 如何调用它仅显示内容,然后返回主程序?

3 投票
1 回答
971 浏览
提问于 2025-04-16 10:42

抱歉问了个小白问题,但我真的不太明白这个。

我在用 Python 和 tkinter,想要显示一些东西(比如,一个画布上有几个形状),并且希望它能一直显示,直到程序退出。我知道在调用 tkinter.tk.mainloop() 之前,任何控件都不会显示。但是,如果我调用了 tkinter.tk.mainloop(),那么在用户关闭主窗口之前,我就无法做其他事情了。

我不需要监控用户的输入事件,只是想显示一些东西。有没有什么好的方法可以做到这一点,而不需要把控制权交给 mainloop

编辑:

这个示例代码合理吗:

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

编辑2(添加了 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

1 个回答

3

Tk需要一个事件循环,这是无法避免的。这是小部件(比如按钮、文本框等)在被遮挡时知道自己需要重新绘制的方式。所以,你必须让事件循环一直在运行。

你至少有三种选择。第一种是把图形界面(GUI)放在主线程里,而把其他逻辑放在一个单独的线程中。第二种选择是使用两个独立的进程——一个负责图形界面,另一个负责你的程序。你的程序可以通过一个套接字与图形界面通信,把需要显示的数据发送过去。

第三种选择是学会在事件循环中生活。毕竟,事件循环其实就是一个包裹着你整个程序的while True循环。如果你的主要逻辑是循环运行的,只需把这个循环去掉,换成事件循环就可以了。例如,你可以运行一次你的代码,然后调用after来安排它在几毫秒后再次运行。这个after的调用会添加一个事件,让你的代码在图形界面完成必要的维护后再执行。

撰写回答