Python - 如何在函数中间等待用户触发?
Python - how to wait for user trigger in the middle of a function?
我想提示用户在函数中间选择是和否,然后相应地继续该函数。怎么可能?
这是我的代码:
def download_popup(file_name, url, size, threshold):
root = Tk()
label = Label(root,
text="The file {file} at {url} is {size}Bytes large which is larger than your threshold({threshold})."
"\nShall I still download it?".format(file_name, url, size, threshold))
yes = ttk.Button(root, width=5, text="yse",
command=lambda: return True)
no = ttk.Button(root, width=5, text="no",
command=lambda: return False)
label.grid(column=0, row=0, colspan=2)
yes.grid(column=0, row=1)
no.grid(column=1, row=1)
mainloop()
# somewhere else in the middle of a function I have:
if response.getheader('Content-Length') > setting.download_threshold_var.get():
# I want the function to wait in this line:
if download_popup(file, url, response.getheader('Content-Length'), setting.download_threshold_var.get()):
out_file.write(response.read())
当然我的代码是胡说八道,我只是为了更好地展示我真正想要的东西。
顺便说一下,我可以通过将函数拆分为 3 个函数来修复它,第一个函数调用 download_popup() 并且 download_popup 根据用户调用第二个或第三个函数选择,但我想要一个更优雅的解决方案。
您可以使用 Button
小部件的 command
属性来调用 def
。
这意味着您不必为了得到用户的答复而搁置一切。您可以只设置两个 def
(或一个并在开始时传入不同的参数)并在按下按钮时调用它们。
见下文:
from tkinter import *
root = Tk()
def yes():
print("The user pressed yes, now do something you fool!")
def no():
print("Oh no, they pressed no. Quick, panic!")
yes = Button(root, text="Yes", command=yes)
no = Button(root, text="No", command=no)
yes.pack()
no.pack()
root.mainloop()
如果您需要使用一个函数来完成此操作,您可以使用类似以下的函数:
from tkinter import *
root = Tk()
def callback(self, *args):
print(boolean.get())
boolean = BooleanVar()
boolean.trace("w", callback)
yes = Button(root, text="Yes", command=lambda: boolean.set(True))
no = Button(root, text="No", command=lambda: boolean.set(False))
yes.pack()
no.pack()
root.mainloop()
最简单的解决方案是使用预定义对话框之一,例如 askyesno
。如果你想要自己的对话框,模式是创建一个 Toplevel
的实例,然后调用 wait_window
,在 window 被销毁之前,它不会 return。
使用预定义的对话框
在python3中,内置对话框在子模块messagebox
中。要提出 yes/no 问题,您可以使用 askyesno
。例如:
import tkinter as tk
from tkinter import messagebox
def download_popup(file_name, url, size, threshold):
...
answer = tk.messagebox.askyesno("Confirmation", "The file...")
if answer:
print("you answered yes")
else:
print("you answered no")
创建您自己的对话框
关键是创建一个顶层,然后等待它被销毁。要从对话框中获取值,您可以使用全局变量或实例变量。
通常最好使用 class 而不是全局变量,但为了简单起见,我将给出一个使用全局变量的答案:
def download_popup(file_name, url, size, threshold):
global result
result = False
def do_yes():
global result
result = True
dialog.destroy()
def do_no():
global result
result = False
dialog.destroy()
dialog = tk.Toplevel()
...
dialog.wait_window(dialog)
print("you chose %s" % result)
我想提示用户在函数中间选择是和否,然后相应地继续该函数。怎么可能?
这是我的代码:
def download_popup(file_name, url, size, threshold):
root = Tk()
label = Label(root,
text="The file {file} at {url} is {size}Bytes large which is larger than your threshold({threshold})."
"\nShall I still download it?".format(file_name, url, size, threshold))
yes = ttk.Button(root, width=5, text="yse",
command=lambda: return True)
no = ttk.Button(root, width=5, text="no",
command=lambda: return False)
label.grid(column=0, row=0, colspan=2)
yes.grid(column=0, row=1)
no.grid(column=1, row=1)
mainloop()
# somewhere else in the middle of a function I have:
if response.getheader('Content-Length') > setting.download_threshold_var.get():
# I want the function to wait in this line:
if download_popup(file, url, response.getheader('Content-Length'), setting.download_threshold_var.get()):
out_file.write(response.read())
当然我的代码是胡说八道,我只是为了更好地展示我真正想要的东西。
顺便说一下,我可以通过将函数拆分为 3 个函数来修复它,第一个函数调用 download_popup() 并且 download_popup 根据用户调用第二个或第三个函数选择,但我想要一个更优雅的解决方案。
您可以使用 Button
小部件的 command
属性来调用 def
。
这意味着您不必为了得到用户的答复而搁置一切。您可以只设置两个 def
(或一个并在开始时传入不同的参数)并在按下按钮时调用它们。
见下文:
from tkinter import *
root = Tk()
def yes():
print("The user pressed yes, now do something you fool!")
def no():
print("Oh no, they pressed no. Quick, panic!")
yes = Button(root, text="Yes", command=yes)
no = Button(root, text="No", command=no)
yes.pack()
no.pack()
root.mainloop()
如果您需要使用一个函数来完成此操作,您可以使用类似以下的函数:
from tkinter import *
root = Tk()
def callback(self, *args):
print(boolean.get())
boolean = BooleanVar()
boolean.trace("w", callback)
yes = Button(root, text="Yes", command=lambda: boolean.set(True))
no = Button(root, text="No", command=lambda: boolean.set(False))
yes.pack()
no.pack()
root.mainloop()
最简单的解决方案是使用预定义对话框之一,例如 askyesno
。如果你想要自己的对话框,模式是创建一个 Toplevel
的实例,然后调用 wait_window
,在 window 被销毁之前,它不会 return。
使用预定义的对话框
在python3中,内置对话框在子模块messagebox
中。要提出 yes/no 问题,您可以使用 askyesno
。例如:
import tkinter as tk
from tkinter import messagebox
def download_popup(file_name, url, size, threshold):
...
answer = tk.messagebox.askyesno("Confirmation", "The file...")
if answer:
print("you answered yes")
else:
print("you answered no")
创建您自己的对话框
关键是创建一个顶层,然后等待它被销毁。要从对话框中获取值,您可以使用全局变量或实例变量。
通常最好使用 class 而不是全局变量,但为了简单起见,我将给出一个使用全局变量的答案:
def download_popup(file_name, url, size, threshold):
global result
result = False
def do_yes():
global result
result = True
dialog.destroy()
def do_no():
global result
result = False
dialog.destroy()
dialog = tk.Toplevel()
...
dialog.wait_window(dialog)
print("you chose %s" % result)