【问题标题】:Tkinter ignores root.after delayTkinter 忽略 root.after 延迟
【发布时间】:2021-11-07 18:57:17
【问题描述】:

Tkinter 忽略 root.after 倒计时动画播放,但它忽略延迟并在倒计时结束之前执行root.after 之后的所有操作

所有测试都表明倒计时正在发生并且变量正在改变,它只是跳过了延迟

def StartTheSpam():
    global TimeLable, ErrorLabel
    #destoryes error labels and the countdown timer
    try:
        for child in root.winfo_children():
            if child == TimeLable or child == ErrorLabel:
                child.destroy()
    except NameError:
        pass
    #needed for fail-safe 1
    mouse = MouseController()

    countdown_value = 5
    counter = tk.StringVar()
    counter.set(countdown_value)
    TimeLable = tk.Label(frame, textvariable=counter, padx=10, pady=5, bg=Modes[mode.get()][3]['background'], fg=Modes[mode.get()][2]['text'])
    TimeLable.pack()

    #coundown
    for countdown in range(1, countdown_value):
        root.after(1000 * countdown, counter.set, countdown_value - countdown)
    x = 100
    y = 100
    try:
        with open(PreferencesStorage['FilePath'], 'r') as SpamText: 
            while PreferencesStorage['loop']:
                for word in SpamText:
                    #fail safe 1
                    if x < 21 and y < 21:
                        break
                    TempX, TempY = mouse.position
                    x = int(TempX)
                    y = int(TempY)
                    #fail-safe 2
                    if keyboard.is_pressed('ctrl+d'):
                        break
                    keyboard.write(word)
                    print(word)
                #return to begining when at end, thats why its outside of the loop
                SpamText.seek(0)
            for word in SpamText:
                keyboard.write(word)
    except FileNotFoundError:
        NoFile = tk.Label(frame, text = 'Please Select A File', padx=10, pady=5, fg=Modes[mode.get()][2]['text'], bg=Modes[mode.get()][3]['background'])
        NoFile.pack()

【问题讨论】:

  • 你认为.after()在做什么?

标签: python python-3.x tkinter


【解决方案1】:

root.after 不会导致延迟。那就是“请让主循环稍后调用此函数”。您的代码将非常快速地将 5 个计时器回调请求排队,然后继续。回调将在稍后发生。

当您为 GUI 编写代码时,您必须开始考虑事件驱动编程。当您创建小部件或调用“pack”时,什么都不会发生。所做的只是排队等待稍后处理的消息。在将来的某个时间点,当mainloop 能够执行时,您的消息将被弹出并处理。只有这样,您的可见屏幕才会改变。这需要改变你的编程方式。您设置屏幕,启动主循环,然后等待事件。你的事件回调改变状态并返回,后台的Tk会更新屏幕。

【讨论】:

  • 我想添加一条关于 while PreferencesStorage['loop']: 的评论,它会中断 .mainloop()
  • 一个有效的点。当您读取该文件并处理击键时,tkinter 主循环未运行,您的 GUI 将无响应。在进行事件驱动编码时,您必须有不同的想法。
  • 如何将其更改为事件驱动编程?甚至驱动编程是什么意思?以及如何更改类型以使其不干扰主循环?
  • @richmail 很难说,因为我们不知道您想要达到什么目标以及您在哪个环境中这样做。您需要提供minimal reproducible example。但一个好的开始可能是搜索 tkinter events 以及如何使用 .after 获取 coroutine 并将您的内容放入由该协程调用的函数中。
猜你喜欢
  • 2015-01-21
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多