从 tkinter 函数中暂停

Pausing from within a tkinter function

我正在尝试创建几个按顺序执行操作的函数。首先他们需要打开一个新的 window 并显示一个标签,然后他们需要等待几秒钟,然后他们需要调用另一个函数。但是,我正在努力让函数等待,我尝试过的所有方法(.after、.sleep、.wait_visibility)似乎都被忽略了,它只是不暂停地跳到下一个函数调用。

这是我的(抱歉,如果有点乱,我是 python 的新手):

from tkinter import *
import time

root =Tk()
root.geometry('600x600')

def scale_screen(event = None):
    global s_screen
    s_screen = Toplevel(root)
    s_screen.title('Residual Inhibition Tester')
    s_screen.geometry('600x600')
    s_screen.transient(root) 
    s_screen.bind('<Return>', sel)
    global var 
    var = IntVar()
    scale = Scale(s_screen, variable = var, orient = HORIZONTAL, length = 1000)
    scale.focus_set()
    scale.pack(anchor=CENTER) 
    button = Button(s_screen, text="Select", command=sel)
    button.pack(anchor=CENTER)

def sel(event = None):
    label = Label(s_screen)
    selection = "Value = " + str(var.get())
    label.config(text = selection)   
    interval_screen()

def interval_screen():
    global i_screen
    i_screen = Toplevel(root)
    i_screen.geometry('600x600')
    i_screen.transient(root)
    i_label = Label(i_screen, text = "Please Wait")
    i_label.pack(anchor = CENTER)
    s_screen.destroy()
    i_screen.after(3000, masker_screen) 
    #time.sleep(3)
    #i_screen.after(300,i_label.configure(text="Playing New Masker Noise")) 
    #root.wait_visibility(window = i_screen) 




def masker_screen():
    global m_screen
    m_screen = Toplevel(root)
    m_screen.geometry('600x600')
    m_screen.transient(root) 
    m_label = Label(m_screen, text = "Playing New Masker Noise").pack(anchor = CENTER)
    m_screen.after(3000, lambda: scale_screen(event = None))
    i_screen.destroy()

b1 = Button(root, command = scale_screen).pack(anchor=CENTER)
root.bind('<Return>', scale_screen)
root.mainloop()

在这个例子中,程序将 运行 但只是完全跳过 interval_screen 而只执行 masker_screen。我也不反对只使用一个屏幕并使用 .configure 方法更改标签文本(如果这样更容易的话)。

谢谢!

没有看到你尝试过的所有方法,就不可能知道你做错了什么。一般来说,你永远不应该调用 time.sleep,也不应该只用一个参数调用 after。此外,当您使用带有两个参数的 after 时,第二个参数必须是对函数的引用。

正确的方法是让第一个函数通过 after:

调用第二个函数
def interval_screen():
    ...
    i_screen.after(3000, maker_screen)

def masker_screen():
    ...
    m_screen.after(3000, lambda: scale_screen(event = None))

请注意,在您更新的问题中,您使用 after 不正确:

m_screen.after(3000, scale_screen(event = None))

您正在立即调用函数 scale_screen(...),并将其结果提供给 after 函数。如果您需要将参数传递给函数,则必须创建另一个 not 需要参数的函数。最简单的方法是使用 lambda,但您也可以使用 functools.partial 或者您可以创建自己的函数。