【问题标题】:Detecting a keypress in python while in the background在后台检测python中的按键
【发布时间】:2023-03-03 17:39:01
【问题描述】:

我正在尝试找到一种方法来检测按键,然后根据它是什么键运行一个方法。

我已经可以用 Tkinter 做到这一点。但我不能做的是在窗口在后台时检测按键。我会在玩游戏时在后台运行这个程序。我需要它能够在我玩游戏时检测输入。

有什么方法可以用 Tkinter 或其他东西来做到这一点?最好我不想下载任何外部的东西,因为我想把它分发给其他人。

【问题讨论】:

  • 你是说你想检测所有键盘活动,比如键盘记录器,或者只是一个键来让程序再次进入前台?在后一种情况下,您的桌面环境的热键配置可能很幸运。
  • Autokey 是一个检测按键和运行脚本的程序。它是用python编写的。检查它的源代码。尤其是 IOMediator 类 - code.google.com/p/autokey/source/browse/trunk/src/lib/…
  • 操作系统不会将关键事件发送到后台程序,因此您需要pykeyloggerpyhook 之类的东西
  • 这是在什么平台上?

标签: python


【解决方案1】:

pyHook 似乎可以很好地解决这个问题(由 furas 提到)

from pyHook import HookManager
from win32gui import PumpMessages, PostQuitMessage

class Keystroke_Watcher(object):
    def __init__(self):
        self.hm = HookManager()
        self.hm.KeyDown = self.on_keyboard_event
        self.hm.HookKeyboard()


    def on_keyboard_event(self, event):
        try:
            if event.KeyID  == keycode_youre_looking_for:
                self.your_method()
        finally:
            return True

    def your_method(self):
        pass

    def shutdown(self):
        PostQuitMessage(0)
        self.hm.UnhookKeyboard()


watcher = Keystroke_Watcher()
PumpMessages()

【讨论】:

  • 这个有 ubuntu 替代品吗?
【解决方案2】:

也从您的按键事件中获取所有属性。您可以执行以下操作

import pythoncom, pyHook

def OnKeyboardEvent(event):
    print('MessageName:',event.MessageName)
    print('Message:',event.Message)
    print('Time:',event.Time)
    print('Window:',event.Window)
    print('WindowName:',event.WindowName)
    print('Ascii:', event.Ascii, chr(event.Ascii))
    print('Key:', event.Key)
    print('KeyID:', event.KeyID)
    print('ScanCode:', event.ScanCode)
    print('Extended:', event.Extended)
    print('Injected:', event.Injected)
    print('Alt', event.Alt)
    print('Transition', event.Transition)
    print('---')

# return True to pass the event to other handlers
    return True

# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.KeyDown = OnKeyboardEvent
# set the hook
hm.HookKeyboard()
# wait forever
pythoncom.PumpMessages()

现在知道按键的所有细节并在此基础上进行操作。

按 's' 看起来像这样

MessageName: key down
Message: 256
Time: 449145375
Window: 2558060
WindowName: "file name"
Ascii: 115 s
Key: S
KeyID: 83
ScanCode: 31
Extended: 0
Injected: 0
Alt 0
Transition 0

【讨论】:

    【解决方案3】:

    我建议不要再使用 pyHook,因为它是一个旧的、未维护的库(最后更新于 2008) 或者,还有许多其他库正在积极维护,例如pynput

    from pynput.keyboard import Key, Listener
    
    
    def on_press(key):
        print('{0} pressed'.format(key))
    
    
    def on_release(key):
        print('{0} release'.format(key))
        if key == Key.esc:
            return False
    
    
    with Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()
    

    keyboard 可能是另一个值得考虑的替代方案。

    【讨论】:

    • 我最终陷入了无限循环。我怎样才能只听第一个按键被按下?如果我按下Esc,我的程序就会进入一个奇怪的状态,没有任何东西打印出来。
    猜你喜欢
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2013-08-17
    • 1970-01-01
    • 2010-09-22
    相关资源
    最近更新 更多