Dmitrii, в общем, потыкался я в ваш код и у меня только еще больше вопросов появилось, например, мне совсем непонятно что за магию здесь делает string. А в целом я так понял, что вы предлагаете тоже самое, что и другие: перед каждым следующем действием в функции осуществлять проверку было ли нажатие клавиши. Единственное вы что-то знаете про то какие косяки могут возникнуть при таком подходе и для этого предложили использовать два потока. При этом, как использовать ваш код я так и не понял, но вот, что при помощи него все-таки удалось реализовать.
import threading
import time
import random
import string
import pyautogui
import keyboard
stop = False
def checkEvent(mutex):
while True:
if mutex.locked():
mutex.release()
print("Mutex released", "=" * 30)
else:
mutex.acquire()
print("Mutex locked", "=" * 30)
time.sleep(0.5)
def longFunc(string, mutex):
while len(string) > 10: # ℳагия, без которой почему-то не будет работать
time.sleep(0.5)
print('Начинаем выполнение основной функции mainProc')
mainProc()
while mutex.locked():
time.sleep(0.1) # or do whatever you need
print('Поток заблокирован!')
else:
print(string, 'Если видишь этот текст, значит магия со string закончилась и что-то пошло не так.')
def mainProc():
pyautogui_move(150, 0, 0.5, pyautogui.easeOutQuad)
pyautogui_move(0, 150, 0.5, pyautogui.easeOutQuad)
pyautogui_move(-150, 0, 0.5, pyautogui.easeOutQuad)
pyautogui_move(0, -150, 0.5, pyautogui.easeOutQuad)
def pyautogui_move(*args):
if stop == False: # унылая проверка... и в реальном коде такие проверки
# придется прописывать чуть ли не для каждой функции,
# и не дай бог, если придется что-то менять в логике,
# ибо менять эту строчку придется для каждой подобной функции,
# а их могут быть сотни;
# по идее эта проверка должна как-то автоматически прописываться
# после каждой команды внутри функции mainProc(), если это осуществляемо
pyautogui.move(*args)
def button_start_command():
print("СТАРТ")
global stop
stop = False
def button_stop_command():
print("ОСТАНОВКА")
global stop
stop = True
if __name__ == "__main__":
s = "".join(random.choices(string.ascii_uppercase + string.digits, k=1000))
mutex = threading.Lock()
t1 = threading.Thread(target = longFunc, args = (s, mutex))
t2 = threading.Thread(target = checkEvent, args = (mutex, ))
t1.start()
t2.start()
keyboard.add_hotkey('a', button_start_command)
keyboard.add_hotkey('s', button_stop_command)
t1.join()
t2.join()
Dmitrii, а вы можете дать пример кода? А то так на словах вообще не понятно, как такое реализовать. Я не нашел никаких методов, чтобы контролировать работу функций или потоков и прерывать их "на горячую" в любой момент при нажатии кнопки.
Первый вариант выглядит сложным, но и как реализовать второй вариант тоже не понятно. По сути сейчас, при выполнении цикла по рисованию курсором квадрата, программа способна зарегистрировать, что нажата кнопка, и в таком случае по сути прерывает цикл, но прерывает его только после окончания текущего витка. Если бы существовал какой-то метод, типа "break mainProc()", который можно было бы вызвать из другой функции в рамках асинхронной работы обеих функций, и таким образом через одну функцию прерывать работу другой, то тогда асинхронность мне бы помогла. Однако ни о каких-либо способов прямого контроля за выполнением функции или потока с возможностью его экстренного прерывания по кнопке я не нашел.
Hemul GM, понятно. Тогда насчет метода на смещение: я не знаю что это, вы можете помочь и показать как это? Вообще, в реальной примере у меня функция mainProc() не только курсором двигает, но и щелкает кнопки мыши и выполняет более сложные методы, например может вызывать самописную функцию с drag and drop. И еще, вы упомянули, что код синхронный, а я ведь вроде многопоточность в него засунул. Может тогда можно резко остановить выполнение потока, в котором будет функция mainProc()?
Нет, я хочу, чтобы прервалось сразу после нажатия кнопки, то есть и во время смещения курсора тоже должно прерываться. Кроме того, такой способ будет несколько ухудшать читаемость и заставляет прописывать проверку фактически после каждой строчки кода.
Этот вариант имеет две проблемы:
1) программа каждый раз дожидается конца выполнения метода move() и не способна прервать его выполнение сразу после нажатия кнопки;
2) этот способ заметно ухудшает читаемость кода и при этом заставляет прописывать проверку после каждого шага.
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.