当弹出对话框时,用户无法与根窗口交互(例如,通过单击“打开对话框”按钮),这是预期的行为。但是,如果用户尝试以任何方式与popup
窗口进行交互,则由于绑定到<FocusOut>
而失去焦点并关闭:
def on_focus_out(e):
self.popup.withdraw()
self.popup.bind('<FocusOut>', on_focus_out)
有些东西正在从无边框窗口偷走焦点。如果省略grab_set()
或overrideredirect(True)
行,则互动不会生成<FocusOut>
事件。所以我似乎无法将事件限制在对话框和与popup
交互而不会同时失去焦点。为什么会发生这种情况?我该如何解决?
下面是一个更简单的程序版本,可以重现同样的问题。
from Tkinter import *
class Dialog(Toplevel):
def __init__(self, parent):
Toplevel.__init__(self, parent)
self.frame = Frame(self)
self.entry = Entry(self.frame)
self.button = Button(self.frame, text='Show')
self.popup = Toplevel(self)
self.popup.transient(self)
self.popup.overrideredirect(True)
self.popup.withdraw()
self.popup.config(bg='red')
self.entry.pack(side=LEFT, expand=True, fill=BOTH)
self.button.pack(side=LEFT)
self.frame.pack(expand=True, fill=X, anchor=N)
def on_focus_out(e):
self.popup.withdraw()
self.popup.bind('<FocusOut>', on_focus_out)
def popup():
w = self.winfo_width()
h = 100
x = self.winfo_rootx()
y = self.winfo_rooty() + self.frame.winfo_height()
geometry = "{0}x{1}+{2}+{3}".format(w, h, x, y)
self.popup.geometry(geometry)
self.popup.deiconify()
self.popup.focus_set()
self.button.config(command=popup)
if __name__ == '__main__':
root = Tk()
opendlg_bttn = Button(root, text='Open Dialog')
opendlg_bttn.pack(fill='none', expand=True)
def open_dialog():
dialog = Dialog(root)
dialog.transient(root)
dialog.grab_set()
dialog.wait_window()
opendlg_bttn.config(command=open_dialog)
root.mainloop()