windows 使用 pyhook 响应组合键(不仅仅是单次击键)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4581772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:53:39  来源:igfitidea点击:

Using pyhook to respond to key combination (not just single keystrokes)?

pythonwindowsautomationkeyboardkeyboard-shortcuts

提问by reckoner

I've been looking around but I can't find an example of how to use pyhook to respond to key combinationssuch as Ctrl+ Cwhereas it is easy to find examples of how to respond to single keypresses such as Ctrlor Cseparately.

我一直在环顾四周,但找不到有关如何使用 pyhook 响应诸如+ 之类的组合键的示例,而很容易找到如何响应诸如或单独按键之类的单个按键的示例。CtrlCCtrlC

BTW, I'm talking about Python 2.6 on Windows XP.

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

Any help appreciated.

任何帮助表示赞赏。

采纳答案by Rod

Have you tried to use the GetKeyStatemethod from HookManager? I haven't tested the code but it should be something like this:

您是否尝试过使用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

Here is further documentation on GetKeyState

这是关于 GetKeyState 的进一步文档

回答by Anon

Actually Ctrl+C have it's own Ascii code (which is 3). Something like this works for me:

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

import pyHook,pythoncom

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

回答by Hugh Bothwell

You can use the following code to watch what pyHook returns:

您可以使用以下代码查看 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()

using this, it appears that pyHook returns

使用这个,看起来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)

(Python 2.7.1、Windows 7、pyHook 1.5.1)

回答by watersnake

I didn't have luck with any of the other answers, so this is what I took to doing

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

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()