@SoftHardcore

Как немедленно прервать выполнение указанной функции при нажатии на кнопку?

Нужно, чтобы после нажатия на клавишу "s" или кнопку STOP, выполнение функции mainProc() тут же прерывалось. То есть, например, чтобы эта функция, которая "рисует" курсором квадрат, тут же переставала водить курсором, если в этот момент была нажата кнопка.

import time
import keyboard
import pyautogui
import threading
from tkinter import *


root = Tk()
root.title("Label")


time.sleep(0.5)


stop = True


def button_stop_command():
    global stop
    stop = True


def button_start_command():
    global stop
    if stop == True:
        stop = False
        while stop == False:
            mainProc()


def button_starter():
    t = threading.Thread(target=button_start_command)
    t.start()


button_start = Button(root, text="START", padx=30, pady=20, command=button_starter)
button_start.grid(columnspan=1, row=1,column=0)

button_stop = Button(root, text="STOP", padx=32, pady=20, command=button_stop_command)
button_stop.grid(row=2, column=0)


keyboard.add_hotkey('a', button_starter)
keyboard.add_hotkey('s', button_stop_command)


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)


root.mainloop()


Уточняю, что необходимо именно прервать сразу при нажатии кнопки. Вот пример кода, который при нажатии кнопки "d" способен прервать программу, из-за чего движение курсора тут же прекращается. Однако это решение завершает работу всей программы, а нужно прервать выполнение только функции, ну или конкретного потока.

Посмотреть пример

stop = True
exit = False


def buttonStartCommand():
    global stop
    if stop == True:
        stop = False
        while stop == False:
            mainProc()


def buttonStopCommand():
    global stop
    stop = True


def buttonExitCommand():
    global exit
    exit = True


def buttonStarter():
    t = threading.Thread(target=buttonStartCommand)
    t.start()


keyboard.add_hotkey('a', buttonStarter)
keyboard.add_hotkey('s', buttonStopCommand)
keyboard.add_hotkey('d', buttonExitCommand)


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)


while not exit:
    time.sleep(0.04)

  • Вопрос задан
  • 2169 просмотров
Пригласить эксперта
Ответы на вопрос 3
HemulGM
@HemulGM Куратор тега Python
Delphi Developer, сис. админ
Он и прервется, когда из функции выйдет
Хочешь, чтоб между смещениями мыши прервалось, делай после каждого вызова проверку
Ответ написан
@Wearant
def button_start_command():
    global stop
    if stop == True:
        stop = False
        mainProc()

def mainProc():
    while 1:
        pyautogui.move(150, 0, 0.5, pyautogui.easeOutQuad)
        if stop == True:
            break
        pyautogui.move(0, 150, 0.5, pyautogui.easeOutQuad)
        if stop == True:
            break
        pyautogui.move(-150, 0, 0.5, pyautogui.easeOutQuad)
        if stop == True:
            break
        pyautogui.move(0, -150, 0.5, pyautogui.easeOutQuad)
        if stop == True:
            break
Ответ написан
@dima20155
you don't choose c++. It chooses you
Если вы хотите прерывать код по какому-то событию практически в произвольном месте (в любой момент), то тогда вам необходим объект класса, который будет определять каким функциям сейчас работать (своеобразный scheduler), то есть работать ли основной программе или же работать обработчику нажатия кнопки, движения мыши. В данном случае имеет смысл говорить о вытесняющей многозадачности.

Если же вы не хотите строить сложную кастомную систему, то можете написать, например, асинхронный код (поскольку в основе уже есть определенный scheduler) и реализовать свою логику вытеснения одних задач другими.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы