我为一个键盘记录器创建了一个线程,该线程与另一个产生一些声音的线程并行记录(我希望捕获反应时间)。
不幸的是,虽然我调用了killKey()并且打印了“invoked killkey()”,但线程永远不会完成。
我总是从这个帖子中得到一个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)。
答案 0 :(得分: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.
答案 1 :(得分: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()