如何从Tkinter的弹出窗口中获取值?

时间:2017-09-04 23:59:06

标签: python python-3.x tkinter

我尝试使用一个Entry和一个Button创建一个弹出窗口。我需要将用户输入的任何内容输入该条目并返回到我的主窗口。我使用的是Python 3.6.0。我有以下代码(灵感来自this question的代码):

from tkinter import *


class Application(Frame):    
    def __init__(self, master=None):
        super().__init__(master)

        self.server_address = None

        self.master = master
        self.master.title('Application')
        self.master.resizable(width=False, height=False)
        self.master.minsize(width=800, height=600)
        self.master.maxsize(width=800, height=600)

        self.grid()
        self.init_menubar()

    def init_menubar(self):
        menubar = Menu(self.master)
        self.master.config(menu=menubar)

        filemenu = Menu(menubar, tearoff=False)
        filemenu.add_command(label="Set remote server", command=self.call_server_config)
        filemenu.add_command(label="Set refresh delay", command=None)
        filemenu.add_separator()
        filemenu.add_command(label="Close", command=self.master.destroy)
        menubar.add_cascade(label='File', menu=filemenu)

        helpmenu = Menu(menubar, tearoff=False)
        helpmenu.add_command(label="Help", command=None)
        menubar.add_cascade(label='Help', menu=helpmenu)

    def call_server_config(self):
        popup = ServerConfig(self.master)
        self.master.wait_window(popup.top)
        print('DEBUG:', popup.value)
        self.create_widgets()


class ServerConfig(Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.top = Toplevel(master)
        self.label = Label(self.top, text="Server address")
        self.label.pack()
        self.entry = Entry(self.top)
        self.entry.pack()
        self.button = Button(self.top, text='Ok', command=self.top.destroy())

        self.value = self.entry.get()


if __name__ == '__main__':
    root = Tk()
    app = Application(master=root)
    app.mainloop()

这给了我错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\<...>\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "D:/Documents/<...>/tk-client.py", line 45, in call_server_config
    popup = ServerConfig(self)
  File "D:/Documents/<...>/tk-client.py", line 60, in __init__
    self.button = Button(self.top, text='Ok', command=self.top.destroy())
  File "C:\Users\<...>\Python\Python36\lib\tkinter\__init__.py", line 2363, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "C:\Users\<...>\Python\Python36\lib\tkinter\__init__.py", line 2293, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: bad window path name ".!application.!toplevel"

1 个答案:

答案 0 :(得分:2)

这段代码引起了异常:

self.button = Button(self.top, text='Ok', command=self.top.destroy())

原因是因为在创建按钮时首先评估了self.top.destroy()。因此,您无法将按钮放在self.top上,因为它已被销毁。您需要将其更改为:

self.button = Button(self.top, text='Ok', command=self.top.destroy)

command=self.top.destroy仅在按下按钮时执行self.top.destroy