当窗口不在焦点时,pygame捕获键盘事件

时间:2012-11-14 14:39:16

标签: python pygame keyboard-events

我编写了一个简单的python脚本,可以控制游标到操纵杆。我的方法是here,以便了解其工作原理。现在它完美无缺,但是,一旦我开始使用操纵杆的脚本,鼠标就没用了,因为只要有新的操纵杆事件进入,我的python例程就会将值设置回原来的状态。

因此,只要按下键盘的键,我就希望忽略我的操纵杆事件。我遇到了pygame.key.get_pressed()方法,但这似乎只有,如果pygame窗口是焦点。我希望这个脚本在后台运行。我是否应该开始使用非pygame事件来收听键盘,或者是否有办法通过pygame跟踪与背景中识别的操纵杆事件类似的键盘事件?

2 个答案:

答案 0 :(得分:3)

我希望pygame设置自己的“沙箱”,以便很难检测到窗口外的输入。您之前的问题表明您还在使用win32api模块。我们可以用它来检测全局按键。

在全局范围内检测按键的正确方法是使用SetWindowsHookEx设置键盘挂钩。不幸的是,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然后检查”循环一样,此方法可能使用比等效“设置回调和等待”方法更多的CPU周期。您可以延长sleep周期的长度来改善这一点,但是密钥检测需要更长时间。例如,如果您睡了一整秒,则在按键和禁用操纵杆之间可能需要一秒钟。

答案 1 :(得分:0)

当你的窗口获得或失去焦点时,你得到一个ACTIVEEVENT。它是gainstate属性告诉您您获得或失去的状态。最简单的解决方案可能是在主事件循环中捕获此事件并使用它们来跟踪您关注或不关注的天气。如果你没有焦点,你可以忽略操纵杆事件。