从 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
或者您可以创建自己的函数。
我正在尝试创建几个按顺序执行操作的函数。首先他们需要打开一个新的 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
或者您可以创建自己的函数。