Автокликер с привязкой к кнопкам в gui и горячим клавишам одновременно

Я новичок в Python. Пишу автокликер, который должен реагировать на кнопки "Старт" и "Стоп" и выполнять те же функции по горячим клавишам "6" и "7".

from tkinter import *
import mouse
import keyboard
import time

window = Tk()
window.title('clicker')
window.wm_attributes('-topmost', True)
window.geometry('250x250')
window.resizable(False, False)


def start():
        btn_stop['state'] = 'active'
        btn_start['state'] = 'disabled'
        while btn_stop['state'] == 'active':
            mouse.click()
            window.update()
            time.sleep(0.01)


def stop():
    btn_start['state'] = 'active'
    btn_stop['state'] = 'disabled'

keyboard.add_hotkey('7', stop)
keyboard.add_hotkey('6', start)
btn_start = Button(window, text='Старт', command=start, state='active')
btn_start.place(width=70, y=120, x=90)

btn_stop = Button(window, text='Стоп', command=stop, state='disabled')
btn_stop.place(width=70, y=60, x=90)

window.mainloop()

По кнопкам программа работает отлично, но если запустить через горячую клавишу "6", то через клавишу "7" остановить её не получается, получается только через кнопку "Стоп". При этом если запускать программу через кнопку "Старт", то через клавишу "7" она спокойно останавливается.

Я догадываюсь (могу ошибаться, ведь всех тонкостей я не знаю), что по каким то причинам keyboard.add_hotkey не реагирует на любую другую клавишу, пока команда предыдущей не будет выполнена (а у меня там бесконечный цикл).

Может я ошибаюсь, но прошу вашей помощи. Мне не нужно чтобы сохранялась конкретно такая модель кода, главное чтобы программа работала и реагировали на клавиши и кнопки одинаково. Надеюсь на отклик.


Ответы (1 шт):

Автор решения: Александр

Ответ на мой же вопрос: совершенно случайно наткнулся на модуль threading позволяющий многопоточно (одновременно) выполнять задачи. Всё оказалось проще простого, немного отредактировал код и всё заработало как по маслу.

from tkinter import *
import mouse
import keyboard
import time
import threading

window = Tk()
window.title('clicker')
window.wm_attributes('-topmost', True)
window.geometry('250x250')
window.resizable(False, False)


def start():
        btn_stop['state'] = 'active'
        btn_start['state'] = 'disabled'
        while btn_stop['state'] == 'active':
            mouse.click()
            window.update()
            time.sleep(0.01)


def stop():
    btn_start['state'] = 'active'
    btn_stop['state'] = 'disabled'
    window.update()

def starting_threading():
    start_threading = threading.Thread(target=start)
    start_threading.start()

keyboard.add_hotkey('6', starting_threading)
keyboard.add_hotkey('7', stop)
btn_start = Button(window, text='Старт', command=start, state='active')
btn_start.place(width=70, y=120, x=90)

btn_stop = Button(window, text='Стоп', command=stop, state='disabled')
btn_stop.place(width=70, y=60, x=90)

window.mainloop()

Довольно комично получилось, до последнего не хотел задавать вопрос, надеялся найти решение сам. В итоге так и случилось.

→ Ссылка