pyHook + pythoncom 在按键次数过多后停止工作 [Python]

2 投票
1 回答
2443 浏览
提问于 2025-04-16 03:53

这是我的脚本:

import pyHook
import pythoncom

hookManager = pyHook.HookManager()

def onKeyboardEvent(event):
     if event.KeyID == 113: # F2
        #do something#
     return True

hookManager.KeyDown = onKeyboardEvent
hookManager.HookKeyboard()
pythoncom.PumpMessages()

在键盘事件中,指定的键(或者我脚本中的F2键)被按了几次之后,脚本就停止工作了……

有人知道为什么会这样吗?或者怎么解决这个问题?

每次发生这种情况我都得重启脚本,而且在我的脚本里我需要按很多次这个键……

1 个回答

3

也许你可以把这个函数放到一个线程里去异步执行,也就是让它在后台运行。你可以把这些任务放到你自己的队列里,或者设置一个条件,如果它已经在运行,就不再执行,这样就能避免消息泵被填满而导致失败。
选项 1. 这个方法会把函数的执行添加到线程的队列中:

    import pythoncom, pyHook, threading
    lock = threading.Lock()  
    def myFunc(i):
        lock.acquire() #execute next function until previous has finished
        #some code
        lock.release()

    def OnKeyboardEvent(event):
        keyPressed = chr(event.Ascii)
        if keyPressed == 'z':
            t = threading.Thread(target=myFunc, args=(1,)) #added to queue
            t.start()
        return True

    hm = pyHook.HookManager()
    hm.KeyDown = OnKeyboardEvent
    hm.HookKeyboard()
    pythoncom.PumpMessages()

选项 2. 这个方法则会在它忙的时候忽略其他的处理调用:


    def myFunc(i):
        myFunc.isRunning = True
        #some code
        myFunc.isRunning = False
    myFunc.isRunning = False

    def OnKeyboardEvent(event):
        keyPressed = chr(event.Ascii)
        if keyPressed == 'z':
            if not myFunc.isRunning: #if function is being executed ignore this call
                t = threading.Thread(target=myFunc,args=(1,))
                t.start()
        return True

当然,当你添加代码时,要小心捕捉异常,否则线程可能会一直被阻塞。

撰写回答