Сбой программы при использовании кнопки «Стоп» - PullRequest
0 голосов
/ 09 июля 2019

Я довольно новичок в Python, но у меня есть рабочая версия этого в MATLAB, но я пытаюсь заставить кнопки пуска / остановки работать в Python.

Я попытался упростить мой кодопубликовано ниже столько, сколько я думаю, что я могу, но в основном я хочу провести серию звуковых сигналов для фитнес-теста.Существует определенный порядок, в котором должны звучать гудки, чтобы обозначить различные интенсивности упражнений.

Я использовал функции для написания различных типов упражнений (я не включил все это в код ниже, чтобысэкономить место), а затем еще один, чтобы объединить их в нужный протокол.Затем я создал кнопки для запуска и остановки работы протокола.

Единственное, что я хочу включить, это не тот пример, который я привел в то, что я уже пробовал, - это включение таймера.Разделы упражнения имеют переменную длину, но должны соответствовать временному периоду, а не определенному числу итераций.

Я уже пробовал несколько ответов на сайте, самый близкий к моей проблеме, я думаю; Предыдущий ответ Первое решение, опубликованное здесь Майком - SMT работает на моем ПК, оно также очень похоже на то, что я пытаюсь достичь, но я попытался сопоставить его настолько близко, насколько смогу, но кнопка запускавсе еще остается в нажатом состоянии, и кнопка «стоп» прерывает работу.

# Import all modules    
import time
import winsound
import tkinter

# Define Global Variables    
runTime = 20
numberBlocks = 5
atime = 1
tracker = False

# Define Movement Functions    
def walk()    
def jog()    
def cruise()    
def sprint()    
def ar()    
def rest()

# callback functions    
def start():
    global numberBlocks, runTime, atime, tracker
    tracker = False
    t = time.time()
    i = 0
    while i < numberBlocks - 1 and tracker == False:
        while (time.time() - t) < runTime and tracker == False:
            if tracker == False and (time.time() - t) < runTime:
                walk()
            if tracker == False and (time.time() - t) < runTime:
                sprint()
            if tracker == False and (time.time() - t) < runTime:
                ar()
            if tracker == False and (time.time() - t) < runTime:
                jog()
            if tracker == False and (time.time() - t) < runTime:
                cruise()
        rest()
        i += 1

def stop():
    global tracker
    tracker = True

# run GUI    
root = tkinter.Tk()
tracker = False
root.title('LIST')

# create all of the main containers    
bottom_center_frame = tkinter.Frame(root)
bottom_center_frame.pack(side="top", fill="x")

# create widgets for the button frame    
button_stop = tkinter.Button(bottom_center_frame, text='Stop', command=stop).pack(side="bottom", fill="x")
button_start = tkinter.Button(bottom_center_frame, text='Start', command=start).pack(side="bottom", fill="x")

# loop gui    
root.mainloop()

Все сигналы работают нормально, просто происходит сбой, когда я пытаюсь остановить его.

1 Ответ

0 голосов
/ 09 июля 2019

Итак, основная проблема здесь в том, что после того, как вы нажмете кнопку «Пуск» и запустите команду в главном цикле, tkinter будет ждать, пока эта команда не закончится, прежде чем позволить вам сделать что-то еще (в этом случае нажмите «Стоп»).
Возможное решение - использовать .after(), например, так:

import tkinter as tk


class FitnessApp(tk.Tk):
    def __init__(self, tracker):
        tk.Tk.__init__(self)

        self.runTime = 20
        self.numberBlocks = 5
        self.atime = 1
        self.tracker = tracker

        # create all of the main containers
        self.bottom_center_frame = tk.Frame(self)
        self.bottom_center_frame.pack(side="top", fill="x")

        # create widgets for the button frame
        self.button_stop = tk.Button(self.bottom_center_frame, text='Stop', command=self.stop)
        self.button_stop.pack(side="bottom", fill="x")
        self.button_start = tk.Button(self.bottom_center_frame, text='Start', command=self.start)
        self.button_start.pack(side="bottom", fill="x")

    def walk(self):
        print("walking")

    def start(self):
        self.tracker = False
        self.move()

    def stop(self):
        print("Stopping run")
        self.tracker = True

    def move(self):
        if self.tracker is False:
            self.walk()
            self.after(1000, self.move)


# run GUI
tracker = False
root = FitnessApp(tracker)
root.title('LIST')

# loop gui    
root.mainloop()

При нажатии кнопки «Пуск» трекер устанавливается на «Ложь», а затем вызывается функция перемещения, которая печатает «ходьба».
Затем self.after(1000, self.move) рекурсивно вызывает функцию перемещения каждые 1000 мс, что позволяет вам нажать кнопку остановки, установить для трекера значение True и остановить симуляцию.

В более сложных ситуациях я рекомендую использовать модуль потоков , который позволяет запускать моделирование во вторичном потоке, сохраняя контроль над основным циклом.Таким образом, вы можете использовать переменную, чтобы отслеживать ход вашей симуляции и действовать соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...