python - pygame在窗口未聚焦时捕获键盘事件

标签 python pygame keyboard-events

我编写了一个简单的 python 脚本,可以控制操纵杆的光标。我了解其工作原理的方法已记录在 here 中。现在,它可以完美地工作,但是,一旦我启动脚本来使用操纵杆,鼠标就没用了,因为每当有新的操纵杆事件进入时,我的 python 例程都会将值设置回其原始值。

因此,我希望只要按下键盘上的某个键,我的操纵杆事件就被忽略。我遇到了 pygame.key.get_pressed() 方法,但这似乎只有在 pygame 窗口处于焦点状态时才有效。我希望这个脚本在后台运行。我应该开始使用非 pygame 事件来监听键盘,还是有办法跟踪类似于操纵杆事件的键盘事件(通过 pygame 在后台识别)?

最佳答案

我希望 pygame 设置自己的“沙箱”,这样就很难检测到来自窗口外部的输入。您上一个问题表明您也在使用 win32api 模块。我们可以用它来检测全局按键。

在全局范围内检测按键的正确方法是使用 SetWindowsHookEx 设置键盘 Hook 。不幸的是,win32api 没有公开该方法,因此我们必须使用效率较低的方法。

GetKeyState方法可用于确定某个键是按下还是按下。您可以连续检查某个键的状态,以了解用户最近是否按下或释放了该键。

import win32api
import time

def keyWasUnPressed():
    print "enabling joystick..."
    #enable joystick here

def keyWasPressed():
    print "disabling joystick..."
    #disable joystick here

def isKeyPressed(key):
    #"if the high-order bit is 1, the key is down; otherwise, it is up."
    return (win32api.GetKeyState(key) & (1 << 7)) != 0


key = ord('A')

wasKeyPressedTheLastTimeWeChecked = False
while True:
    keyIsPressed = isKeyPressed(key)
    if keyIsPressed and not wasKeyPressedTheLastTimeWeChecked:
        keyWasPressed()
    if not keyIsPressed and wasKeyPressedTheLastTimeWeChecked:
        keyWasUnPressed()
    wasKeyPressedTheLastTimeWeChecked = keyIsPressed
    time.sleep(0.01)

警告:与任何“while True sleep and then check”循环一样,此方法可能比等效的“设置回调并等待”方法使用更多的 CPU 周期。您可以延长 sleep 时间的长度来改善这种情况,但按键检测将花费更长的时间。例如,如果您 sleep 了一整秒,则从按下某个键到禁用操纵杆之间最多可能需要一秒钟的时间。

关于python - pygame在窗口未聚焦时捕获键盘事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13380938/

相关文章:

python - 在pygame中旋转时,船向上和向左移动的速度比向下和向右移动的速度快

python - Ubuntu18.04(Virtualbox) 上滑动背景的问题

c# - 如何在控制台应用程序中处理按键事件

python - 如何将字典的动态值写入csv python

python - 使用 itertools 的排列爆炸内存

python - 在 SymPy 中选择不同的表达式分解

Python - 使用Flipkart API的参数

python - 在 pygame 中移动 cometd

swift - 键盘作为游戏 Controller ,在 Swift 中处理多个键

javascript - 函数执行一次且 addEventlistener 无效