Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 12, 2015 19:58:50

Luca_Brasi
Зарегистрирован: 2015-11-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Подвисает поток

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

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version