我有一个程序在运行时需要对模块进行输入,所以我实现了一个简单的对话框来从用户那里获取输入,以便在我的Tkinter程序中使用。但我也需要它在作为控制台程序运行模块时超时,在用户没有与它交互时跳过它或在这么多秒后超时。不要让它一直坐在那里等待,直到用户与它交互。超时后我如何终止窗口?这是我现在拥有的。。。
def loginTimeout(timeout=300):
root = tkinter.Tk()
root.withdraw()
start_time = time.time()
input1 = simpledialog.askinteger('Sample','Enter a Number')
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13: # enter_key
break
elif ord(chr) >= 32: #space_char
input1 += chr
if len(input1) == 0 and (time.time() - start_time) > timeout:
break
print('') # needed to move to next line
if len(input1) > 0:
return input1
else:
return input1
不完全确定问题是什么,但您可以使用类似于以下的tkinterafter()
方法:
import tkinter as tk
root = tk.Tk()
root.geometry('100x100')
def get_entry() -> str:
"""Gets and returns the entry input, and closes the tkinter window."""
entry = entry_var.get()
root.destroy() # Edit: Changed from root.quit()
return entry
# Your input box
entry_var = tk.StringVar()
tk.Entry(root, textvariable=entry_var).pack()
# A button, or could be an event binding that triggers get_entry()
tk.Button(root, text='Enter/Confirm', command=get_entry).pack()
# This would be the 'timeout'
root.after(5000, get_entry)
root.mainloop()
因此,如果用户输入了一些内容,他们可以点击确认或启动绑定到该条目的事件,或者在延迟之后,程序无论如何都会运行get_entry。也许这会给你一个想法,你也可以看看其他的小部件方法:https://effbot.org/tkinterbook/widget.htm
EDIT:我不确定这在你的程序中是如何安排的,但root.mainloop()
会阻塞,所以一旦它运行,它之后的代码就不会运行,直到mainloop((退出。如果您的函数是顶级((窗口的一部分,则可以使用wait_window()
来阻止函数前进,直到您的超时破坏了顶级窗口或用户之前调用了该函数。这个例子虽然可能不是最好的解决方案,但应该是:
def loginTimeout(timeout_ms: int=5000):
root = tk.Tk()
root.geometry('200x50')
# function to get input and change the function variable
input_ = ''
def get_input():
nonlocal input_
input_ = entry_var.get()
root.destroy()
# build the widgets
entry_var = tk.StringVar()
tk.Entry(root, textvariable=entry_var).pack(side='left')
tk.Button(root, text='Confirm', command=get_input).pack(side='right')
# timeout
root.after(timeout_ms, get_input)
# mainloop
root.mainloop()
# won't get here until root is destroyed
return input_
print(loginTimeout())