从tkinter函数中暂停

时间:2015-01-12 16:52:12

标签: python tkinter

我试图创建一些按顺序执行操作的函数。首先,他们需要打开一个新窗口并显示一个标签,然后他们需要等待几秒钟,然后他们需要调用另一个函数。但是,我努力让函数等待,我尝试过的所有方法(。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方法来更改标签文本,如果这更容易的话。

谢谢!

1 个答案:

答案 0 :(得分:2)

如果没有看到你尝试过的所有方法,就不可能知道你做错了什么。一般来说,你永远不应该打电话给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函数。如果需要将参数传递给函数,则必须创建另一个需要参数的函数。最简单的方法是使用lambda,但您也可以使用functools.partial,也可以创建自己的函数。