Tkinter专注于撤回框架(实际上是WINDOW)

时间:2014-03-20 01:04:19

标签: tkinter setfocus

所以我希望顶层框架在撤回后保持焦点。

    from Tkinter import *
class VanishingFrame():
    def __init__(self,parent,Event=None):
        self.parent=parent
        self.visible=True
        self.Frame=Toplevel()
        self.Frame.title('Magical disapearing frame')
        self.Frame.transient(self.parent)
        self.Frame.grab_set()
        self.Frame.focus_set()
        self.Frame.geometry('300x300+150+150')
        Label(self.Frame,text="Press any key").place(relx=.5,rely=0.5,anchor=CENTER)
        self.Frame.bind('<Key>',self.AnyKey)
        self.AnyKey()
    def AnyKey(self,Event=None):
        print "key hit"
        self.visible= not self.visible
        if self.visible:
            self.Frame.withdraw()
        else:
            self.Frame.deiconify()
        self.parent.update()
        self.Frame.update()
        self.Frame.grab_set()
        self.Frame.focus_set()
        self.Frame.focus_force()
        self.Frame.update()
root=Tk()
root.geometry('500x500')
root.title("Bring out your dead")
Magic=VanishingFrame(root);
root.mainloop()

第一个关键点按预期工作,VanishingFrame消失。然而,焦点现在似乎在根框架上。单击根框架中的任何位置将导致焦点切换回消失的帧,然后下一个按键将使其重新出现。有趣的是,当撤消消失帧并且根框架似乎具有焦点时,您无法关闭根框架。您必须单击根框架中的某个位置并显示消失的框架然后将其关闭。那会告诉我self.Frame.transient正在工作。

所以实际的问题是如何在不必先点击根框架的情况下将注意力集中在撤回的框架上?

1 个答案:

答案 0 :(得分:1)

尝试设置焦点时,Tk检查窗口是否已映射。如果焦点目标未映射,则会忽略您的请求。见tkFocus.c::TkSetFocusWin。看起来好像是一个坏主意,特别是与抓斗相结合。如果你有合成支持,你可以使用属性设置alpha通道并使其透明(例如:self.Frame.attributes('-alpha', 0.0)。因为它仍然会被映射(但不可见),它可以接受焦点。

在这种情况下添加grab set命令可以覆盖将焦点设置为未映射的小部件的限制。如果焦点设置为应用程序中的有效窗口小部件,则抓取将生效并将焦点移动到抓取的窗口小部件树中。

最初指定的问题是如何在取消当前顶层时将焦点重新附加到有用的东西,并且答案是使用wm deiconify .将主顶层重新断言为当前活动窗口。这会将顶层设置为活动状态,并将焦点设置到此窗口上,然后抓取该窗口并将其移动到现在隐藏的顶层窗口小部件。此时,键绑定将再次起作用。