pyHook键盘记录器线程未结束
我创建了一个线程,用来记录按键,同时还有另一个线程在播放声音(我想测量反应时间)。
不过,那个记录按键的线程一直没有结束,尽管我调用了killKey(),而且“调用了killKey()”这句话也被打印出来了。
我总是得到这个线程的状态是active(活跃)的,也就是thread.isActive() = true。
class KeyHandler(threading.Thread):
hm = pyHook.HookManager()
def __init__(self):
threading.Thread.__init__(self)
def OnKeyboardCharEvent(self,event):
print 'Key:', event.Key
if event.Key=='E':
...
return True
def killKey(self):
KeyHandler.hm.UnhookKeyboard()
ctypes.windll.user32.PostQuitMessage(0)
print "invoked killkey()"
def run(self):
print "keyHandlerstartetrunning"
KeyHandler.hm.KeyDown = self.OnKeyboardCharEvent
KeyHandler.hm.HookKeyboard()
#print "keyboardhooked"
pythoncom.PumpMessages()
更具体一点,ctypes.windll.user32.PostQuitMessage(0) 似乎没有任何作用。
我更倾向于使用一个外部的超时机制来调用killKey(),或者在这个线程中调用ctypes.windll.user32.PostQuitMessage(0)。
2 个回答
1
我觉得pbackup的解决方案不错。总结一下,我找到了一种方法,就是自己发送一个键,而不是等用户输入。这可能不是最好的办法,但在我的计时线程中,它是最快的,并且可以和其他计时程序同时进行。
STOP_KEY_HANDLER = True
# send key to kill handler - not pretty but works
for hwnd in get_hwnds_for_pid (GUIWINDOW_to_send_key_to.pid):
win32gui.PostMessage (hwnd, win32con.WM_KEYDOWN, win32con.VK_F5, 0)
# sleep to make sure processing is done
time.sleep(0.1)
# kill window
finished()
2
要使用PostQuitMessage这个功能,必须在同一个线程中发送。为此,你需要引入一个全局变量 STOP_KEY_HANDLER
。如果你想退出程序,只需在任何线程中将全局变量 STOP_KEY_HANDLER = True
设置为真,这样在下一个按键时程序就会退出。你的按键处理程序必须在主线程中运行。
STOP_KEY_HANDLER = False
def main():
pass # here do all you want
#bla bla
global STOP_KEY_HANDLER
STOP_KEY_HANDLER = True # This will kill KeyHandler
class KeyHandler:
hm = pyHook.HookManager()
def OnKeyboardCharEvent(self,event):
if STOP_KEY_HANDLER:
self.killKey()
print 'Key:', event.Key
if event.Key=='E':
pass
return True
def killKey(self):
global STOP_KEY_HANDLER
if not STOP_KEY_HANDLER:
STOP_KEY_HANDLER = True
return None
KeyHandler.hm.UnhookKeyboard()
ctypes.windll.user32.PostQuitMessage(0)
print "invoked killkey()"
def _timeout(self):
if self.timeout:
time.sleep(self.timeout)
self.killKey()
def run(self, timeout=False):
print "keyHandlerstartetrunning"
self.timeout = timeout
threading.Thread(target=self._timeout).start()
KeyHandler.hm.KeyDown = self.OnKeyboardCharEvent
KeyHandler.hm.HookKeyboard()
#print "keyboardhooked"
pythoncom.PumpMessages()
k=KeyHandler()
threading.Thread(target=main).start()
k.run(timeout=100) # You can specify the timeout in seconds or you can kill it directly by setting STOP_KEY_HANDLER to True.