Python - 如何在函数中间等待用户触发器?

时间:2017-09-27 11:01:48

标签: python user-interface tkinter triggers wait

我想提示用户在函数中间选择yes和no,然后相应地继续该函数。怎么可能?

这是我的代码:

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根据用户选择调用第二个或第三个函数,但我想要一个更优雅的解决方案。 / p>

2 个答案:

答案 0 :(得分:2)

最简单的解决方案是使用其中一个预定义的对话框,例如askyesno。如果你想要自己的对话框,那么模式是创建一个Toplevel的实例,然后调用wait_window,它将在窗口被销毁之前不会返回。

使用预定义的对话框

在python 3中,内置对话框位于子模块messagebox中。要问是/否问题,您可以使用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")

创建自己的对话框

关键是创建一个顶层,然后等待它被销毁。要从对话框中获取值,可以使用全局变量或实例变量。

通常最好使用类而不是全局变量,但简单性我会给出一个使用全局变量的答案:

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)

答案 1 :(得分:0)

您可以使用command窗口小部件的Button属性来呼叫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()