在tkin中使用wait_window()时,如何返回列表框的选定项

2021-01-17 14:52:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望我的tkinter应用程序将列表框的选定项从被调用窗口(classMyDialog)返回到调用窗口(classExample)。如果不使用wait_window(),则返回一个空列表。使用wait_window()会导致错误消息。在我看来,wait帴u window()阻塞了curseelection()方法。需要更改什么才能正常返回?在

下面的示例是this answer的修改版本。在

import tkinter as tk

class MyDialog(object):
    def __init__(self, parent):
        self.toplevel = tk.Toplevel(parent)

        choices = ("one", "two","three")
        names = tk.StringVar(value=choices)

        label = tk.Label(self.toplevel, text="Pick something:")
        self.listbox = tk.Listbox(self.toplevel, listvariable=names, height=3,
            selectmode="single", exportselection=0)
        button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)

        label.pack(side="top", fill="x")
        self.listbox.pack(side="top", fill="x")
        button.pack()

    def show(self):
        self.toplevel.wait_window()

        value = self.listbox.curselection()
        return value

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.button = tk.Button(self, text="Click me!", command=self.on_click)
        self.label = tk.Label(self, width=80)
        self.label.pack(side="top", fill="x")
        self.button.pack(pady=20)

    def on_click(self):
        result = MyDialog(self).show()
        self.label.configure(text="your result: %s" % result)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
2条回答
网友
1楼 ·

wait_window等待直到寡妇被摧毁。既然它被销毁了,你就不能从widget中提取任何信息。在

您必须设置绑定,以便在变量更改时将数据保存到变量中,以便在小部件被销毁后可以获取它。在

网友
2楼 ·

布莱恩·奥克利的回答让我找到了下面的解决方案。非常感谢你!在

import tkinter as tk

class MyDialog(object):
    def __init__(self, parent):
        self.toplevel = tk.Toplevel(parent)

        choices = ("one", "two","three")
        names = tk.StringVar(value=choices)

        label = tk.Label(self.toplevel, text="Pick something:")
        self.listbox = tk.Listbox(self.toplevel, listvariable=names, height=3,
            selectmode="single", exportselection=0)
        button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)

        label.pack(side="top", fill="x")
        self.listbox.pack(side="top", fill="x")
        button.pack()

        # add binding
        self.listbox.bind('<<ListboxSelect>>', self.getSelection)

    # function associated with binding
    def getSelection(self, event):
        widget = event.widget
        selection=widget.curselection()
        self.value = widget.get(selection[0])

    # separate function for wait_window and the return of the selection
    def returnValue(self):
        self.toplevel.wait_window()
        return self.value

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.button = tk.Button(self, text="Click me!", command=self.on_click)
        self.label = tk.Label(self, width=80)
        self.label.pack(side="top", fill="x")
        self.button.pack(pady=20)

    def on_click(self):
        result = MyDialog(self).returnValue()
        self.label.configure(text="your result: %s" % result)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

相关问题