排除子进程时线程化



我编写了一个程序,用于捕获通过子进程打开的俄罗斯方块上的键盘事件。不,当我只想捕获事件而不打开俄罗斯方块我的键盘处理程序(pyHook)不会捕获事件:

# open Tetris
#Tetris = subprocess.Popen (["C:\Program Files (x86)TetrisTetris.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的替代方法

它不工作,由于Qt绕过windows消息循环——pyHook依赖于消息循环的功能。

现代图形界面框架,如Windows窗体,WindowsPresentation Foundation、MFC、Delphi、Qt等则没有通常要求应用程序直接访问Windows消息循环,而是自动路由事件,如按键和控件中定义的相应处理程序框架。

From Message Loop in MS Windows

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.

最新更新