python - 如何不断更新 tkinter 标签直到按下按钮?

标签 python python-3.x tkinter infinite-loop

我正在尝试创建一个简单的计时器应用程序,其中用户按下开始按钮(或使用按键绑定(bind))并且时钟不断更新,直到用户按下停止按钮(或使用按键绑定(bind)),但在尝试创建这个我陷入了无限循环。

我尝试创建一个 bool 标志,其中 True 表示结束更新,并使用 while 循环来检查这一点,但是程序最终陷入了无限循环。这一切都在 python 3.x(特别是 v3.6.7)中。 在提供的代码中,我尽可能地减少了它,同时保留了错误和错误的上下文。我还删除了之前提到的按键绑定(bind),因为这些不是问题的一部分。

import tkinter as tk
class cubeTimer():
    def __init__(self):
        ##Defines parts of timer
        self.start_time = 0.0
        self.end_time = 0.0
        self.difference = 0.0
    def get_time(self,num):
        ##Gets time since epoch
        if num == 1:
            self.start_time = time.time()
        elif num == 2:
            self.end_time = time.time()
    def get_difference(self):
        ##Finds difference bwteen start and end times
        self.difference = self.end_time - self.start_time
        return self.difference
class cubeGUI():
    def __init__(self):
        ##Instance variables for later use
        self.num = 0
        self.time_difference = 0
        self.flag = False
        ##Creates instance of timer class
        self.timer = cubeTimer()
        ##Creates GUI
        self.root = tk.Tk()
        ##Label to show the solve time
        self.time_label = tk.Label(text='-',height=5,width=10)
        self.time_label.grid(row=1,columnspan=2,sticky=tk.W)
        ##Button to start timer
        self.start_button = tk.Button(text='Start',height=5,width=10,command=self.start_process)
        self.start_button.grid(row=2,column=0)
        ##Button to end timer, initialised as disabled
        self.end_button = tk.Button(text='End',state=tk.DISABLED,height=5,width=10,command=self.end_process)
        self.end_button.grid(row=2,column=1)
    def start_process(self):
        ##Sets variable
        self.num = 1
        ##Calls timer to get time
        self.timer.get_time(self.num)
        ##Configures necessary buttons
        self.start_button.configure(state=tk.DISABLED)
        self.end_button.configure(state=tk.NORMAL)
        while self.flag == False:
            self.time_difference = self.timer.get_difference()
            self.time_label.configure(text=self.time_difference)
            time.sleep(0.1)
    def end_process(self):
        ##Sets variable
        self.num = 2
        ##Calls timer to get time
        self.timer.get_time(self.num)
        ##Updates flag
        self.flag = True
        ##Configures necessary button
        self.end_button.configure(state=tk.DISABLED)
        ##Calls time difference
        self.time_difference = self.timer.get_difference()
        ##Puts it on screen
        self.time_label.configure(text=self.time_difference)
myTimer = cubeGUI()

我希望程序每 0.1 秒(或任何给定的时间段)更新一次时间标签,但程序却因为遇到无限循环而卡住并卡住。

最佳答案

您不能在 GUI 内使用循环,因为它会干扰 GUI 主循环。相反,您必须构建程序以集成到主循环中。在 tkinter 中,这是通过 after() 方法完成的。这是您的固定代码(据我可以推断您要做什么),包括适当的类:

import tkinter as tk

class CubeTimer(tk.Frame):
    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)

        self.timer = ' '
        self.time_value = tk.IntVar()

        ##Label to show the solve time
        time_label = tk.Label(self, textvariable=self.time_value,height=5,width=10)
        time_label.grid(row=1,columnspan=2,sticky=tk.W)
        ##Button to start timer
        self.start_button = tk.Button(self, text='Start',height=5,width=10,command=self.start_process)
        self.start_button.grid(row=2,column=0)
        ##Button to end timer, initialised as disabled
        self.end_button = tk.Button(self, text='End',state=tk.DISABLED,height=5,width=10,command=self.end_process)
        self.end_button.grid(row=2,column=1)

    def timer_tick(self):
        self.time_value.set(self.time_value.get() + 1)
        self.timer = self.after(1000, self.timer_tick) # schedule this method to be called again in 1,000 millisconds (1 second)

    def start_process(self):
        ##Configures necessary buttons
        self.start_button.configure(state=tk.DISABLED)
        self.end_button.configure(state=tk.NORMAL)
        self.timer_tick()

    def end_process(self):
        self.after_cancel(self.timer) # cancel the scheduled method call

        ##Configures necessary button
        self.end_button.configure(state=tk.DISABLED)
        self.start_button.configure(state=tk.NORMAL)

def main():
    root = tk.Tk()
    myTimer = CubeTimer(root)
    myTimer.pack()
    root.mainloop()

if __name__ == "__main__":
    main()

关于python - 如何不断更新 tkinter 标签直到按下按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56857006/

相关文章:

php - 是否可以根据 PHP 中的命名空间自动加载文件?

python - Pyglet,播放器,下一首歌

python - Python中将字符串编码为gbk

python - ubuntu filedialog.askdirectory 版本太低

python - pygame 文本变量

python - 为什么我不能用我的 python 脚本打印到终端?

python-3.x - 在 `setup.py` 或 `pyproject.toml` 中指定 Python PIP 参数

python - 使用 sqrt AND ceil 进行埃拉托斯特尼筛法

python - 如何在字典中存储 tkinter 按钮小部件?

tkinter - tkinter 和 wxWidgets 的优缺点?