【问题标题】:How to create GUI objects one by one with Tkinter如何使用 Tkinter 一个一个地创建 GUI 对象
【发布时间】:2017-06-12 19:28:36
【问题描述】:

我喜欢每秒创建一个对象并一个一个地显示。但是,下面的代码会等待 3 秒并同时显示它们。

from tkinter import *
import time
def create():
   for i in range(3):
      r4=Radiobutton(root, text="Option 1"+str(i), value=1)
      r4.pack( anchor = W )
      time.sleep(1)
root = Tk()
create()
root.mainloop()

【问题讨论】:

  • sleep 不适用于 tkinter 的主循环。你应该看看after method

标签: python-3.x time tkinter


【解决方案1】:

您的代码按原样每秒创建一个您希望的对象,但需要显示此对象,并且在代码流到达mainloop 时显示它们。因此,对于观察者来说,一秒钟后似乎根本没有任何物体。

当然,您可以使用 sleepupdate,但要注意 - sleeping 会导致窗口无响应,因此如果您的应用程序不是这样,这是可以的选项(老实说 - 根本不可以)绘制并且你在mainloop之外,但如果不是 - 准备一个“冻结”窗口,因为GUI只能在mainloop中重绘自己(一个事件循环,你也可以使用update到达它)而sleep 阻止了这种行为。

但是有一个很好的替代方法,after 方法,看看吧!

还有一个sn-p,所以你可以看到区别:

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
import time

def create_with_sleep():
    for _ in range(3):
        tk.Radiobutton(frame_for_sleep, text="Sleep Option").pack(anchor='w')
        time.sleep(int(time_entry.get()))
        root.update()

def create_with_after(times=3):
    if times != 0:
        tk.Radiobutton(frame_for_after, text="After Option").pack(anchor='w')
        times -= 1
        root.after(int(time_entry.get()) * 1000, lambda: create_with_after(times))

root = tk.Tk()

test_yard_frame = tk.Frame(root)
frame_for_sleep = tk.Frame(test_yard_frame)
frame_for_after = tk.Frame(test_yard_frame)
test_yard_frame.pack()
frame_for_sleep.pack(side='left')
frame_for_after.pack(side='left')

button_frame = tk.Frame(root)
button_for_sleep = tk.Button(button_frame, text='Create 3 radiobuttons with sleep+update', command=create_with_sleep)
button_for_after = tk.Button(button_frame, text='Create 3 radiobuttons with after', command=create_with_after)
button_frame.pack()
button_for_sleep.pack(side='left')
button_for_after.pack(side='left')

time_label = tk.Label(root, text='Time delay in seconds:')
time_label.pack(fill='x')
time_entry = tk.Entry(root)
time_entry.insert(0, 1)
time_entry.pack(fill='x')

root.mainloop()

延迟 1 秒没有太大区别,但您可以尝试增加延迟以了解为什么 after 选项为 preferable in general

【讨论】:

  • 谢谢!这真的比使用睡眠更好
【解决方案2】:

您可以使用update 对您的对象调用刷新。

在使用时,您必须在 for 循环中添加行 root.update()

【讨论】:

  • 嗨@TimoThund 如果这个答案已经解决了您的问题,请点击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。 当然,没有义务这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 2018-10-20
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多