如何在继续之前等待 Tkinter TopLevel 窗口的结果? [英] How to wait for result from Tkinter TopLevel window before continuing?

查看:22
本文介绍了如何在继续之前等待 Tkinter TopLevel 窗口的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用户单击按钮后,我想创建一个包含建议的新顶层窗口,当用户在顶层窗口中选择他/她的建议并单击完成"按钮时我想销毁顶层窗口并将选定的结果传递给根窗口.这就是我想要实现的目标,但直到现在我都无法正确完成.

After a user clicks on a button, I want to create a new TopLevel window with suggestions and when user selects his/her suggestion on the toplevel window and clicks the button "Done" I want to destroy the toplevel window and pass the selected result to root window. This is what I want to achieve but until now I am not able to do it properly.

我尝试在顶层窗口上使用 wait_window 但这并不是每次都有效,因为有时它不返回任何内容或无限期冻结.

I tried using wait_window on the toplevel window but that didn't work every time as sometimes it does not return anything or freezes indefinitely.

import tkinter as tk

root = None
BTN = None
listbox = None
selected = None
SUGGESTIONS = [(0, "level 1"), (11, "level 2"), (23, "level 3")]

def select():
    global listbox, SUGGESTIONS, selected

    selected = listbox.get(tk.ANCHOR)
    for (idd, info) in SUGGESTIONS:
        if selected == f_info:
                selected = idd

def show_suggestions():
    global SUGGESTIONS, listbox

    win = tk.TopLevel()
    win.title("Select suggestion")
    win.geometry("400x400")
    
    listbox = tk.Listbox(win, height=20, width=40)
    listbox.pack(pady=15)

    self.btn = tk.Button(win, text="Confirm selection", command=select)
    self.btn.pack(pady=10)

    for (idd, info) in SUGGESTIONS :
        self.listbox.insert(tk.END, f_info) 
    
    #TODO: wait for selected suggestion and assign it to global variable selected

def main():
    global root, BTN
    root = tk.Tk()
    root.title("Youtube to MP3")
    root.geometry("575x475")

    BTN = tk.Button(
        master=root,
        text="List suggestions",
        width=25,
        height=5,
        command=show_suggestions
    )
    BTN.pack(pady=15)
    
    root.mainloop()

推荐答案

tkinter 方法 wait_window 完全符合您的要求,尽管您也可以使用 wait_visibility 甚至 <代码>wait_variable.您声称 wait_window 不可靠,但该方法几十年来一直是 tk 的一部分,我个人从未见过它行为不端.

The tkinter method wait_window does exactly what you want, though you could also use wait_visibility or even wait_variable. You claim wait_window is unreliable but that method has been a part of tk for decades and I've personally never seen it misbehave.

我建议用两段代码来实现它:一个实现窗口本身的类,以及一个使用该类来显示窗口并返回所选项目的函数.

I recommend implementing this with two pieces of code: a class that implements the window itself, and a function which uses the class to display the window and return the selected item.

下面举个例子.请注意,值 self.selection 被初始化为 None,然后在用户单击确认选择"时设置为一个值.按钮.另请注意,show 方法将在销毁小部件之前获取此值,以便即使在小部件被销毁后也可以检索该值.

The following gives an example. Notice that the value self.selection is initialized to None, and then set to a value when the user clicks the "Confirm Selection" button. Also notice that the show method will get this value before destroying the widget so that it can be retrieved even after the widget has been destroyed.

class SuggestionPopup(tk.Toplevel):
    def __init__(self, parent, suggestions):
        super().__init__(parent)

        self.title("Select suggestion")

        self.listbox = tk.Listbox(self, height=10, width=20)
        self.listbox.pack(pady=15)

        self.btn = tk.Button(self, text="Confirm selection", command=self.select)
        self.btn.pack(pady=10)

        for (idd, info) in suggestions :
            self.listbox.insert(tk.END, info)

        self.selection = None

    def select(self):
        selection = self.listbox.curselection()
        if selection:
            self.selection = self.listbox.get(selection[0])
        self.destroy()

    def show(self):
        self.deiconify()
        self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
        self.wait_window(self)
        return self.selection

显示它的函数可能看起来像这样:

The function to display it might look something like this:

def get_suggestion():
    suggestions = ((0, "Item 0"), (1, "Item 1"), (2, "Item 2"))
    popup = SuggestionPopup(root, suggestions)
    result = popup.show()
    return result

这篇关于如何在继续之前等待 Tkinter TopLevel 窗口的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆