在用户单击按钮后,我想创建一个带有建议的新顶层窗口,当用户在顶层窗口上选择他/她的建议并单击“完成”按钮时,我想销毁顶层窗口并传递选择结果到根窗口。这就是我想要实现的目标,但直到现在我都无法正确完成。
我尝试在顶级窗口上使用 multi trait_mod:<is>(Sub $fn, :$foo!) {
for $fn.ast.ast-lexical-declarations {
say "Name: " ~ .lexical-name;
when RakuAST::VarDeclaration::Simple { #`( my $x / state $x / ... ) }
when RakuAST::VarDeclaration::Term { #`( my \x = ... ) }
# Others, depending if you care about parameters, placeholder params, implicits, etc.
}
}
但每次都不起作用,因为有时它不返回任何内容或无限期冻结。
wait_window
答案 0 :(得分:2)
tkinter 方法 wait_window
完全符合您的要求,不过您也可以使用 wait_visibility
甚至 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
显示它的函数可能看起来像这样:
def get_suggestion():
suggestions = ((0, "Item 0"), (1, "Item 1"), (2, "Item 2"))
popup = SuggestionPopup(root, suggestions)
result = popup.show()
return result
答案 1 :(得分:0)
好吧,我通过首先检查是否选择了某些东西,然后通过全局引用顶级窗口来销毁顶级窗口来解决它。正如@Bryan Oakley 确认的那样,我还使用 wait_window
等待选择。
最终工作代码:
import tkinter as tk
root = None
BTN = None
listbox = None
selected = None
toplvlwin = None
SUGGESTIONS = [(0, "level 1"), (11, "level 2"), (23, "level 3")]
def select():
global listbox, SUGGESTIONS, selected, toplvlwin
selection = listbox.get(tk.ANCHOR)
for (idd, info) in SUGGESTIONS:
if selection == f_info:
selected = idd
toplvlwin.destroy()
def show_suggestions():
global SUGGESTIONS, listbox, selected, toplvlwin
toplvlwin = tk.TopLevel()
toplvlwin.title("Select suggestion")
toplvlwin.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)
toplvlwin.wait_window()
print(selected) # confirm correct tuple id is returned
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()