Форум сайта python.su
Написал небольшой код по решению нижеописанной задачи. Программа подви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()
Офлайн