@icebeat

Как остановить поток while true нажатием горячих клавиш?

Всем привет! Хочу сделать GUI кликер.

В коде убрал все что связано с интерфейсом, оставил часть, в которой создаю отдельный поток (чтобы программа не зависала), и в нем слушатель нажатия ctrl+f2, он запускает кликер. Этот участок кода работает хорошо. Проблема в том, что при нажатии ctrl+f3 выполнение кода не останавливается:
import sys, pyautogui, keyboard, time
from threading import Thread
 
def mouse_click():
    while True:
        x, y = pyautogui.position()
        pyautogui.click(x, y)
 
        time.sleep(5)
 
        if keyboard.is_pressed('ctrl+f3'):
            break
 
def clicker_start():
    keyboard.add_hotkey('ctrl+f2', lambda: mouse_click())
    keyboard.wait()
 
if __name__ == '__main__':
    t1 = Thread(target=clicker_start)
    t1.start()

Как исправить, чтобы по нажатию ctrl+f3 кликер останавливал работу?
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ответы на вопрос 2
Vindicar
@Vindicar
RTFM!
Потому что is_pressed() проверяет, нажата ли клавиша прямо сейчас. С 99% вероятностью у тебя нажатие начнётся и закончится когда выполняется time.sleep(), потому что он долгий. А потому на момент выполнения is_pressed() клавиша уже будет отпущена.
Проще всего будет заменить один долгий sleep() на цикл из коротких ожиданий и проверок, примерно по 0,1-0,2 секунды.
Ответ написан
Комментировать
from threading import Thread
import pyautogui, keyboard, time


class Clicker:
    def __init__(self):
        self.running = False
        thread_hotkey_listener = Thread(target=self.clicker_start)
        thread_hotkey_listener.start()
        thread_main_action = Thread(target=self.mouse_click)
        thread_main_action.start()

    def mouse_click(self):
        while True:
            if not self.running:
                continue

            x, y = pyautogui.position()
            pyautogui.click(x, y)
            print('Click happened')
            time.sleep(5)

    def start(self):
        self.running = True
        print('Clicking started')

    def stop(self):
        self.running = False
        print('Clicking stopped')

    def clicker_start(self):
        keyboard.add_hotkey('ctrl+f2', self.start)
        keyboard.add_hotkey('ctrl+f3', self.stop)
        keyboard.wait()


Clicker()

Не уверен, что это лучшее решение, но по крайней мере оно работает. В целом можно избавиться от класса и использовать глобальную переменную.
По ctrl+f2 ctrl+f3 программа начинает и заканчивает кликать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы