grab_set可防止无边框窗口被聚焦

时间:2016-09-21 04:06:02

标签: python tkinter

当弹出对话框时,用户无法与根窗口交互(例如,通过单击“打开对话框”按钮),这是预期的行为。但是,如果用户尝试以任何方式与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()

0 个答案:

没有答案