问题
I wrote a script to move the mouse around when a key is pressed using pyHook. The problem is that after 6 key press events the script stops picking up key presses and needs to be ended from task manager.
I am using python 2.7 on a Windows 7 machine. I have not found anyone else with an answer to a similar problem.
The code is designed to hook the mouse, and then once it is clicked move the cursor, unhook the mouse and hook the keyboard. There, the keyboard hook only works for 6 events. If I keep both the mouse and keyboard hooked, each hook works for only 6 events. Does anyone have any ideas what the problem is and how to fix it?
import pythoncom, pyHook, win32api
import math
from time import sleep
# Radius is 250px
radius = 50
# Intervals in the circle
n_intervals = 50
# List of intervals
l_intervals = []
for i in range(0, n_intervals):
l_intervals.append((i+1) * math.pi * 2 / n_intervals)
# Move the cursor in a circle
def move_circle():
(x, y) = win32api.GetCursorPos()
old_pos = (x, y)
center = (x-radius, y)
for i in l_intervals:
p = (radius * math.cos(i), radius * math.sin(i))
new_pos = (int(center[0]+p[0]), int(center[1]-p[1]))
win32api.SetCursorPos(new_pos)
sleep(0.01)
def OnKeyboardEvent(event):
if event.Key == "Media_Play_Pause":
exit()
else:
move_circle()
# return True to pass the event to other handlers
return True
def OnMouseEvent(event):
# called when mouse events are received
if event.MessageName == "mouse left down":
move_circle() # move the cursor
hm.UnhookMouse() # unhook the mouse
hm.HookKeyboard() # hook the keyboard
return True
hm = pyHook.HookManager()
hm.MouseAll = OnMouseEvent
hm.KeyDown = OnKeyboardEvent
# Hook the mouse
hm.HookMouse()
# Wait for any events
pythoncom.PumpMessages()
UPDATE: I found a solution and posted the answer below, but would still appreciate any answers that can explain why I had the problem in the first place, and why the solution fixes it.
回答1:
After more google-searching I found a solution that worked for me: pyHook + pythoncom stop working after too much keys pressed [Python]. I tried his first suggestion, and my problem appears solved. The pyHook part of my code now looks as below.
import pythoncom, pyHook, win32api, sys
import math
import threading, time
from time import sleep
...
#attempt to stop pyHook hang...
lock = threading.Lock()
def KeyEventThread1(i):
lock.acquire()
sys.exit()
lock.release()
def KeyEventThread2(i):
lock.acquire()
move_circle()
lock.release()
def OnKeyboardEvent(event):
if event.Key == "Media_Play_Pause":
t = threading.Thread(target=KeyEventThread1, args=(1,))
t.start()
sys.exit()
else:
t = threading.Thread(target=KeyEventThread2, args=(1,))
t.start()
# return True to pass the event to other handlers
return True
def MouseEventThread(i):
lock.acquire()
sleep(.2) #So that mouse is not depressed when moved
move_circle() # move the cursor
hm.UnhookMouse() # unhook the mouse
lock.release()
def OnMouseEvent(event):
# called when mouse events are received
if event.MessageName == "mouse left down":
t = threading.Thread(target=MouseEventThread, args=(1,))
t.start()
hm.HookKeyboard()
return True
hm = pyHook.HookManager()
hm.MouseAll = OnMouseEvent
hm.KeyDown = OnKeyboardEvent
# Hook the mouse
hm.HookMouse()
# hook the keyboard
# Wait for any events
pythoncom.PumpMessages()
来源:https://stackoverflow.com/questions/14114581/pyhook-stops-capturing-key-events-after-6-presses