如何在启动Tk / Tkinter程序时检查是否保持Shift?

时间:2018-05-25 19:36:40

标签: python tkinter tk

我希望我的Tkinter(Tk 8.6)程序在程序启动时保持Shift时表现不同。

我知道如何检查鼠标和键盘事件中的state属性,但即使用户没有引起任何事件,我的检测也需要工作。

我尝试了<Configure><FocusIn>个事件,但他们的state属性始终为'??'。我尝试生成虚拟事件,但其state属性始终为0

有没有办法从Tk解释器查询此信息?

1 个答案:

答案 0 :(得分:0)

A window can only receive key events when it's focused:

  

KeyPress和KeyRelease事件被发送到当前具有键盘焦点的窗口。

然后:

  • 使用<KeyPress-Shift_L>和/或<KeyPress-Shift_R>来检测Shift键的按下(“Shift”不起作用,它只能是修饰符。)
  • 设置一个标记,以便按照GUI Button hold down - tkinter仅按unbind按键处理程序重复KeyPress个事件。

概念验证应用:

import Tkinter as tkinter

class HoldKeyDetect(object):
    def __init__(self, widget, keys, handler=None):
        """Detect holding `keys` in `widget`"""
        self.widget = widget
        self.handler = handler        
        self.binds = {}
        for key in keys:
            evid = '<KeyPress-%s>'%key
            self.binds[evid] = widget.bind(evid,self.keypress)

    def __del__(self):
        try: self.unbind()
        except tkinter.TclError: pass   #app has been destroyed
    def unbind(self):
        while True:
            try: evid,fid = self.binds.popitem()
            except KeyError: break
            self.widget.unbind(evid, fid)

    def keypress(self,e):
        try:
            if self.handler:
                self.handler(e)
        finally:
            self.unbind()        

class App(object):
    def __init__(self,root):
        self.root = root
        root.focus_force()
        self.h = HoldKeyDetect(root,("Shift_L","Shift_R"),self.set_mode)
        root.after(1000,   # larger than keypress repeat interval + code overhead
                        self.continue_)
        self.mode = False
    def go(self):
        self.root.mainloop()
    def set_mode(self,_):
        print "Shift mode set"
        self.mode = True
    def continue_(self):
        del self.h
        print "Mode=", self.mode
        self.root.destroy()

if __name__ == '__main__':
    App(tkinter.Tk()).go()