阻止输入对话框
Blocking Input Dialog Box
如何在标准 Python 中获得阻塞模态输入对话框?
我需要用户输入一个值才能继续执行代码。
这是一些不工作测试代码,但我的想法是我应该能够从脚本中的任何地方调用MyDialog
,所以这只是一个简化的例子。
import tkinter
class MyDialog:
def __init__(self, prompt):
self.top = tkinter.Toplevel()
tkinter.Label(self.top, text=prompt).pack()
self.e = tkinter.Entry(self.top)
self.e.pack(padx=5)
tkinter.Button(self.top, text="OK", command=self.ok).pack(pady=5)
def ok(self):
self.top.destroy()
return self.e.get()
root = tkinter.Tk()
userName = MyDialog('Enter your name')
tkinter.Label(root, text="Hello {}".format(userName)).pack()
root.mainloop()
该对话框不仅应禁用主 window,而且应阻止调用它的任何代码。并且它应该能够将值传递回调用代码。
解决方案需要两个关键部分。首先,使用 grab_set
阻止另一个 window 中的所有事件(或者更准确地说,将所有事件发送到对话框 window)。其次,使用 wait_window
来防止该方法在对话框被销毁之前返回。
也就是说,您不应该像您的示例中那样使用它。在创建 window 之前,您需要有 mainloop
运行。它可能在某些平台上工作正常,但一般来说,在 mainloop
为 运行.
之前,您不应该期望您的 GUI 能够正常运行
这是一个简单的例子:
import Tkinter as tk
class MyDialog(object):
def __init__(self, parent, prompt):
self.toplevel = tk.Toplevel(parent)
self.var = tk.StringVar()
label = tk.Label(self.toplevel, text=prompt)
entry = tk.Entry(self.toplevel, width=40, textvariable=self.var)
button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)
label.pack(side="top", fill="x")
entry.pack(side="top", fill="x")
button.pack(side="bottom", anchor="e", padx=4, pady=4)
def show(self):
self.toplevel.grab_set()
self.toplevel.wait_window()
value = self.var.get()
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, text="", width=40)
self.label.pack(side="top", fill="x")
self.button.pack(padx=20, pady=20)
def on_click(self):
result = MyDialog(self, "Enter your name:").show()
self.label.configure(text="your result: '%s'" % result)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
如何在标准 Python 中获得阻塞模态输入对话框?
我需要用户输入一个值才能继续执行代码。
这是一些不工作测试代码,但我的想法是我应该能够从脚本中的任何地方调用MyDialog
,所以这只是一个简化的例子。
import tkinter
class MyDialog:
def __init__(self, prompt):
self.top = tkinter.Toplevel()
tkinter.Label(self.top, text=prompt).pack()
self.e = tkinter.Entry(self.top)
self.e.pack(padx=5)
tkinter.Button(self.top, text="OK", command=self.ok).pack(pady=5)
def ok(self):
self.top.destroy()
return self.e.get()
root = tkinter.Tk()
userName = MyDialog('Enter your name')
tkinter.Label(root, text="Hello {}".format(userName)).pack()
root.mainloop()
该对话框不仅应禁用主 window,而且应阻止调用它的任何代码。并且它应该能够将值传递回调用代码。
解决方案需要两个关键部分。首先,使用 grab_set
阻止另一个 window 中的所有事件(或者更准确地说,将所有事件发送到对话框 window)。其次,使用 wait_window
来防止该方法在对话框被销毁之前返回。
也就是说,您不应该像您的示例中那样使用它。在创建 window 之前,您需要有 mainloop
运行。它可能在某些平台上工作正常,但一般来说,在 mainloop
为 运行.
这是一个简单的例子:
import Tkinter as tk
class MyDialog(object):
def __init__(self, parent, prompt):
self.toplevel = tk.Toplevel(parent)
self.var = tk.StringVar()
label = tk.Label(self.toplevel, text=prompt)
entry = tk.Entry(self.toplevel, width=40, textvariable=self.var)
button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)
label.pack(side="top", fill="x")
entry.pack(side="top", fill="x")
button.pack(side="bottom", anchor="e", padx=4, pady=4)
def show(self):
self.toplevel.grab_set()
self.toplevel.wait_window()
value = self.var.get()
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, text="", width=40)
self.label.pack(side="top", fill="x")
self.button.pack(padx=20, pady=20)
def on_click(self):
result = MyDialog(self, "Enter your name:").show()
self.label.configure(text="your result: '%s'" % result)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()