Автокликер с привязкой к кнопкам в 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()
Довольно комично получилось, до последнего не хотел задавать вопрос, надеялся найти решение сам. В итоге так и случилось.