每当tkinter中的tkraise()引发时,更新/更新倒数框架

时间:2018-11-16 01:26:58

标签: python python-3.x tkinter

我正在尝试创建一个具有多个窗口的2分钟倒计时应用程序。我将所有窗口(框架)放入主容器中,然后每当单击特定窗口的导航按钮时,使用tkraise()来升高框架(例如:如果“返回起始页面”按钮是点击)。 仅当首次创建PracticePage类的对象时,下面的代码才能正常工作。 但是,当我从倒数计时器框架(类PracticePage)导航到另一个页面时,计时器仍在后面运行。换句话说,每当我从另一页导航回到倒数计时器页面时,计时器都不会从2分钟开始倒数。我希望每当定时器框架升高时,它就从2分钟开始倒计时。 我是编程的初学者。如果我的问题和代码令人困惑,我深表歉意。有人可以帮忙吗?预先谢谢你。

下面是我的代码:

import tkinter as tk
from tkinter import *
from tkinter import ttk
import time

class App(tk.Tk):   #we want this class to inherit from tk.Tk
    def __init__(self, *args, **kwargs):  
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self,"PreSys")

        container = tk.Frame(self, height = 1000, width =1000)
        container.pack(side="top", fill="both", expand = True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (SignInPage, StartPage, PracticePage):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(SignInPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()   #to raise one of the frames up to the front    


class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)


        self.startButton = ttk.Button(self, text="スタート", command = lambda: controller.show_frame(PracticePage))

        self.startButton.pack()

class PracticePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.timeLeft = tk.Label(self,text= "")
        self.backButton = ttk.Button(self, text="やり直す", command = lambda: controller.show_frame(StartPage))
        self.homeButton = ttk.Button(self, text="サインアウト", command = lambda: controller.show_frame(SignInPage))

        self.timeLeft.pack()
        self.backButton.pack()
        self.homeButton.pack()
        #rc.start_record(SignInPage.entry_name.get())

        self.remaining = 0
        self.countdown(121)

    def countdown(self, remaining = None):
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            self.timeLeft.configure(text="お疲れ様です!")
        else:
            mins, secs = divmod(self.remaining,60)
            mins = round(mins)
            secs = round(secs)
            self.timeLeft.configure(text=str(mins) +"分"+ str(secs) +"秒")
            self.remaining = self.remaining - 1
            self.after(1000, self.countdown)

apps = App()
apps.mainloop()

1 个答案:

答案 0 :(得分:0)

在开始使用该解决方案之前,请提供您的代码,以确保其有效。您删除了SignInPage是因为它不是必需的,但是您没有跟进并删除对其的其他引用(即,self.show_frame(SignInPage)中的App.__init__self.homebutton中的{ PracticePage

关于您重置计时器的问题,有很多解决方法,但是所有这些都归结为您正在做的所有事情都在提高框架:您不包含任何影响{{1 }},具体取决于您当前要切换到的帧。

由于这是一个相对简单的应用程序,因此我将建议最简单的解决方案:当您引发countdown时,请重置其PracticePage变量。为了使它尽可能简单和一致,我们只需要修改remaining

show_frame

在较大的应用程序中,我建议您使用## You should store variables that are meaningful (you can place this underneath the imports) PRACTICETIME = 121 ## App(): def show_frame(self, cont): frame = self.frames[cont] if cont == PracticePage: frame.remaining = PRACTICETIME frame.tkraise() #to raise one of the frames up to the front 完全停止倒计时,或者在合理的情况下直接破坏并重新创建widget.after_cancel()。使用这种方法,您可能会注意到有1秒钟的延迟,此时PracticePage仍显示先前的Pages时间:如果这确实困扰您,那么我建议提取将remaining格式化为自己的函数的代码然后在设置PracticePage.timeLeft之后立即从App.show_frame调用该函数。