Написал небольшой код по решению нижеописанной задачи. Программа подвиcает в самый разный момент. Прошу помочь внести ясность. Попытаюсь изложить все более-менее упрощенно.
Цель: Выводит текущее положении курсора на экране и время сколько он в этом положении пробыл. При нажатии Crtl, прерывать прерывать выполнение, затем выводить координату курсора в момент нажатия Crtl и дальше продолжать делать как на предыдущем шаге. То есть писать координаты.
Текущее решение: Написал все с использованием двух потоков. Первый, непрерывно пишет кординаты, второй перехватывает нажатие клавиш. Если было нажатие, первый поток выводит кординату, второй поток ждет. Далее первый поток снимает ожидание и все продолжает в штатном режиме до следующего нажатия Crtl.
Проблема. Все вроде бы работает, но в некоторый момент может зависать на этапе нажатия кнопки Crtl. Я использовал threading.event(), читал про некоторые сложности с ним, мол может сбрасываться теряться событие и пр. Может это как то быть связано с моим случаем? Да и вообще, может как то можно более надежно решить мою задачу не отходя сильно от идеи двух потоков...
import pyautogui, time, pyxhook, threading
class MouseKeybEvents():
def __init__(self):
self.running=True
# Отслеживает положение курсора
def traceCoursor(self):
lastPos=pyautogui.position()
while self.mustFinish == False:
currPos=pyautogui.position()
time.sleep(0.1)
if lastPos == currPos and self.keyPressed == False:
if self.timerLock == False:
self.timerStart()
else:
# import pdb; pdb.set_trace()
posTime=round(self.timerStop(),1)
print(lastPos,posTime)
timerLock=False
self.resetTimer()
self.event.clear()
self.event.set()
lastPos=currPos
# Инициализирует метод OnKeyboardEvent
def catchKeyPress(self):
hm = pyxhook.HookManager()
hm.KeyDown = self.OnKeyboardEvent
hm.HookKeyboard()
hm.start()
while self.running:
time.sleep(0.1)
hm.cancel()
# Метод опрелеябщий события нажатия кнопок клавиатуры
def OnKeyboardEvent(self,event):
#print(event.Key, event.Ascii)
if event.Ascii == 32:
self.running = False
self.mustFinish = True
elif event.Key == 'Control_L':
self.keyPressed=True
#print(self.event.is_set())
print(self.event.clear())
self.event.wait(1.0)
print(pyautogui.position(), ' LClick')
self.event.clear()
self.keyPressed=False
# Сей объект класса посвящен таймеру
class Timer(MouseKeybEvents):
keyPressed=False
startTime=0
timerLock=False
event=threading.Event()
mustFinish=False
# Ставит базовую точку времени с которой начинается отсчет
def timerStart(self):
self.timerLock=True
self.resetTimer()
self.keyPressed=False
# Останавливает таймер, возвращает разницу времени в секундах между запуском
# и остановкой
def timerStop(self):
self.timerLock=False
timePassed=time.time() - self.startTime
return timePassed
# Сбрасывает таймер, выставляя значение таймера на 0
def resetTimer(self):
self.startTime=time.time()
class ThreadController(Timer):
def createThreads(self):
th1=threading.Thread(target=self.traceCoursor)
th2=threading.Thread(target=self.catchKeyPress)
th1.start()
th2.start()
if __name__ == '__main__':
a = ThreadController()
a.createThreads()