【问题标题】:Using pyhook to respond to key combination (not just single keystrokes)?使用 pyhook 响应组合键(不仅仅是单次击键)?
【发布时间】:2011-06-02 16:17:25
【问题描述】:

我一直在环顾四周,但找不到如何使用 pyhook 响应键 组合 的示例,例如 Ctrl + C 而很容易找到如何分别响应单个按键的示例,例如 CtrlC

顺便说一句,我说的是 Windows XP 上的 Python 2.6。

任何帮助表示赞赏。

【问题讨论】:

    标签: python windows automation keyboard keyboard-shortcuts


    【解决方案1】:

    您是否尝试过使用 HookManager 中的 GetKeyState 方法?我还没有测试过代码,但它应该是这样的:

    from pyHook import HookManager
    from pyHook.HookManager import HookConstants
    
    def OnKeyboardEvent(event):
        ctrl_pressed = HookManager.GetKeyState(HookConstants.VKeyToID('VK_CONTROL') >> 15)
        if ctrl_pressed and HookConstant.IDToName(event.keyId) == 'c': 
            # process ctrl-c
    

    这里是further documentation on GetKeyState

    【讨论】:

    • 您在第五行缺少)
    • 而且 GetKeyState 似乎不存在。
    • 我想它已经转移到pyHook.GetKeyState
    • 比特移位是怎么回事?重要吗?
    • 其实我想捕捉Shift + PrintScreen
    【解决方案2】:

    您可以使用以下代码查看 pyHook 返回的内容:

    import pyHook
    import pygame
    
    def OnKeyboardEvent(event):
        print 'MessageName:',event.MessageName
        print 'Ascii:', repr(event.Ascii), repr(chr(event.Ascii))
        print 'Key:', repr(event.Key)
        print 'KeyID:', repr(event.KeyID)
        print 'ScanCode:', repr(event.ScanCode)
        print '---'
    
    hm = pyHook.HookManager()
    hm.KeyDown = OnKeyboardEvent
    hm.HookKeyboard()
    
    # initialize pygame and start the game loop
    pygame.init()
    while True:
        pygame.event.pump()
    

    使用这个,pyHook 似乎返回了

    c:      Ascii 99, KeyID 67,  ScanCode 46
    ctrl:   Ascii 0,  KeyID 162, ScanCode 29
    ctrl+c: Ascii 3,  KeyID 67,  ScanCode 46
    

    (Python 2.7.1、Windows 7、pyHook 1.5.1)

    【讨论】:

    • 是的,我之前实际上已经尝试过这段代码,但它似乎是单独处理每个按键,即使您同时按住它们。我不认为有组合键的键码。
    【解决方案3】:

    实际上 Ctrl+C 有它自己的 Ascii 代码(即 3)。像这样的东西对我有用:

    import pyHook,pythoncom
    
    def OnKeyboardEvent(event):
        if event.Ascii == 3:
            print "Hello, you've just pressed ctrl+c!"
    

    【讨论】:

    • 虽然这个答案很有用,但我不会赞成。这解决了这种特殊情况,但是如果我想捕获 Shift+PrintScreen 怎么办?
    【解决方案4】:

    我没有任何其他答案的运气,所以这就是我要做的

    class Keystroke_Watcher:
        def __init__(self, master):
            self.hm = HookManager()
            self.hm.KeyDown = self.on_key_down
            self.hm.KeyUp = self.on_key_up
            self.hm.HookKeyboard()
            self.keys_held = set()  # set of all keys currently being pressed
    
        def get_key_combo_code(self):
            # find some way of encoding the presses.
            return '+'.join([HookConstants.IDToName(key) for key in self.keys_held])
    
        def on_key_down(self, event):
            try:
                self.keys_held.add(event.KeyID)
            finally:
                return True
    
        def on_key_up(self, event):
            keycombo = self.get_key_combo_code()
            print(keycombo)
            try:
                # Do whatever you want with your keycombo here
            finally:
                self.keys_held.remove(event.KeyID)
                return True
    
        def shutdown(self):
            PostQuitMessage(0)
            self.hm.UnhookKeyboard()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 2011-05-06
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2018-01-28
      • 1970-01-01
      相关资源
      最近更新 更多