排除子进程时的线程

时间:2014-05-13 12:13:40

标签: python multithreading subprocess

我写了一个程序来捕获俄罗斯方块上的键盘事件,这是通过子进程打开的。不,当我只想在没有打开俄罗斯方块的情况下捕获事件时,我的键盘处理程序(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的替代方案吗?

2 个答案:

答案 0 :(得分:1)

由于Qt绕过了Windows消息循环,它无法正常工作 - pyHook依赖消息循环来运行。

  

现代图形界面框架,例如Windows Forms,Windows   Presentation Foundation,MFC,Delphi, Qt 和其他人没有   通常要求应用程序直接访问Windows消息   循环,而是自动路由按键和按键等事件   鼠标点击其中定义的适当处理程序   框架。

来自Message Loop in MS 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.