Lin*_*der 1 python user-interface tkinter
用户单击按钮后,我想创建一个包含建议的新顶级窗口,当用户在顶级窗口上选择他/她的建议并单击“完成”按钮时,我想销毁顶级窗口并将所选结果传递给根窗口。这就是我想要实现的目标,但到目前为止我还无法正确地做到这一点。
我尝试wait_window在顶层窗口上使用,但这并不是每次都有效,因为有时它不会返回任何内容或无限期冻结。
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()
Run Code Online (Sandbox Code Playgroud)
tkinter 方法wait_window完全符合您的要求,尽管您也可以使用wait_visibilityor wait_variable。你声称wait_window不可靠,但这种方法几十年来一直是 tk 的一部分,我个人从未见过它行为不当。
我建议使用两段代码来实现这一点:一个实现窗口本身的类,以及一个使用该类显示窗口并返回所选项目的函数。
下面给出一个例子。请注意,该值self.selection被初始化为None,然后在用户单击“确认选择”按钮时设置为一个值。另请注意,该show方法将在销毁小部件之前获取此值,以便即使在小部件被销毁后也可以检索该值。
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
Run Code Online (Sandbox Code Playgroud)
显示它的函数可能看起来像这样:
def get_suggestion():
suggestions = ((0, "Item 0"), (1, "Item 1"), (2, "Item 2"))
popup = SuggestionPopup(root, suggestions)
result = popup.show()
return result
Run Code Online (Sandbox Code Playgroud)