【问题标题】:Program Crashing When Using Stop Button使用停止按钮时程序崩溃
【发布时间】:2019-07-09 12:30:14
【问题描述】:

我对 python 很陌生,但我在 MATLAB 中有一个工作版本,但很难让开始/停止按钮在 python 中工作。

我已尝试尽可能简化我在下面发布的代码,但基本上我想运行一系列哔哔声以进行体能测试。为了表示不同的运动强度,哔哔声的出现有一定的顺序。

我使用函数来编写不同类型的练习(我没有将所有这些都包含在下面的代码中以节省空间),然后使用另一个函数将它们组合成所需的协议。然后我创建了按钮来启动和停止协议运行。

我想要包含的唯一内容不在我已经尝试过的示例中,它必须包含一个计时器。练习部分是可变长度的,但需要适应一个时间段而不是一定数量的迭代。

我已经在网站上尝试了几个答案,我认为最接近我的问题的答案是; Previous Answer Mike 在此处发布的第一个解决方案 - SMT 在我的 PC 上运行,它看起来也很像我想要实现的目标,但我已尝试尽可能地匹配它,但开始按钮仍然被按下并且停止按钮崩溃工作。

# 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()

哔哔声一切正常,当我尝试停止它时它只是崩溃了。

【问题讨论】:

  • 试着安排你的 while 循环吧?

标签: python tkinter


【解决方案1】:

因此,这里的主要问题是,一旦您单击开始并在主循环中启动命令,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()

点击start时,tracker设置为False,然后调用move函数,打印“walking”。
然后self.after(1000, self.move) 每 1000 毫秒递归调用一次 move 函数,这允许您按下停止按钮,将跟踪器设置为 True 并停止模拟。

对于更复杂的情况,我建议您使用threading module,它允许您在辅助线程中启动模拟,同时保持对主循环的控制。这样您就可以使用变量来跟踪模拟的进度并采取相应的行动。

【讨论】:

  • 感谢您的建议,我之前曾尝试在 self.after 中工作,但没有设法解决我需要的复杂性。我还没有遇到线程,但看起来这可能是我需要研究让它工作。
猜你喜欢
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多