我写了一个程序来捕获俄罗斯方块上的键盘事件,这是通过子进程打开的。不,当我只想在没有打开俄罗斯方块的情况下捕获事件时,我的键盘处理程序(pyHook)无法捕获事件:
# open Tetris
#Tetris = subprocess.Popen (["C:\\Program Files (x86)\Tetris\Tetris.exe"])
#start game by sending "F2" key
#for hwnd in get_hwnds_for_pid (Tetris.pid):
#win32gui.PostMessage (hwnd, win32con.WM_KEYDOWN, win32con.VK_F2, 0)
keyH = KeyHandler()
ToneT = ToneTimer()
keyH.setDaemon(True)
ToneT.setDaemon(True)
keyH.start()
ToneT.start()
这在使用另一个子进程时工作正常,但我不知道为什么现在这样。 KeyHandler不会拿起钥匙。
class KeyHandler(threading.Thread):
def run(self):
# watch for all keyboard events
KeyHandler.hm.KeyDown = self.OnKeyboardCharEvent
# set the hook
KeyHandler.hm.HookKeyboard()
# activate message pipeline
print "keyboardhooked"
pythoncom.PumpMessages()
print "thisshouldnotbeprinted"
除了最后一个语句之外的所有语句都被打印出来了,但是没有打印出被激活的键,而是当我按下一个键时,应用程序会冻结(我有一个函数来捕获包含子进程的工作正常的事件......)
我想离开子进程时线程有问题。
我发现如果在按下某个键之前切换到另一个GUI窗口,然后按一个键,则会接受键并打印键事件。
更精确的信息:这可能与运行OpenSesame(实验软件)内部的脚本有关,因为某种方式pyhook通常不会从他的窗口/窗口检索键盘响应,但只能从gui窗口查找?因此,我可能需要在这里寻找pyhook的替代方案吗?
答案 0 :(得分:1)
由于Qt绕过了Windows消息循环,它无法正常工作 - pyHook依赖消息循环来运行。
现代图形界面框架,例如Windows Forms,Windows Presentation Foundation,MFC,Delphi, Qt 和其他人没有 通常要求应用程序直接访问Windows消息 循环,而是自动路由按键和按键等事件 鼠标点击其中定义的适当处理程序 框架。
答案 1 :(得分:0)
run方法需要有一个循环。线程一旦离开run方法就结束了。
class KeyHandler(threading.Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.running = True
# end
def run(self):
while self.running:
# watch for all keyboard events
KeyHandler.hm.KeyDown = self.OnKeyboardCharEvent
# set the hook
KeyHandler.hm.HookKeyboard()
# activate message pipeline
print "keyboardhooked"
pythoncom.PumpMessages()
print "thisshouldnotbeprinted"
# end run
或者您根本不必将其子类化。
def catch_key(keyboard):
# watch for all keyboard events
KeyHandler.hm.KeyDown = keyboard.OnKeyboardCharEvent
# set the hook
KeyHandler.hm.HookKeyboard()
# activate message pipeline
print "keyboardhooked"
pythoncom.PumpMessages()
print "thisshouldnotbeprinted"
thread = threading.Thread(target=catch_key, args=(Keyboard()))
thread.start()
# Remember to use thread.join() to safely close the thread.