使用tkinter IntVar更新标签

时间:2017-09-06 21:19:27

标签: python tkinter

参加C和汇编课程后,我决定学习python。这是我的第一次尝试,请原谅任何滥用符号的行为。 以下是我为控制生长周期而创建的GUI部分。我在使用IntVar时遇到了问题。我已经创建了一个循环结束的倒计时(参见倒计时方法)。我尝试在Countdown中包含self.remaining标签,它确实显示倒计时,但显示倒计时的标签不会在周期结束时使用取消按钮和time_state标签销毁。将self.remaining标签放在使用IntVar的 init 中时,它会以天,小时,分钟,秒显示初始倒计时,但会保留该初始值,并且不会随着倒计时的重复而更新。不应该以这种方式使用IntVar更新self.remaining标签中的day_val,hour_val,min_val和sec_val吗?

from tkinter import *
import time
class Grow_Cycle():
    def __init__(self): 
        self.time_state = Label(app, text = ("You have selected:\n     "+str(day_val)+" days,\n "+str(hour_val)+" hours,\n "+str(min_val)+" minutes"))
        self.time_state.grid(column = 1, row =1)
        self.bttn_3 = Button(app, text = "Cancel", command = self.cancel)
        self.bttn_3.configure(bg = "red")
        self.bttn_3.grid(row = 2, column = 0, 
                         ipadx = 50, ipady = 20,
                         padx = 20, pady = 100)
        self.temp1 = (day_val * 86400)+(hour_val * 3600)+(min_val * 60)
        self.countdown()                                        
        self.remaining = Label(app, text = ("You have remaining:\n"+str(day_lef.get())+" days,\n"
                                        +str(hour_lef.get())+" hours,\n"
                                        +str(min_lef.get())+" minutes,\n"
                                        +str(sec_lef.get())+" seconds"),
                                        textvariable = (day_lef, hour_lef, min_lef, sec_lef))                                            
        self.remaining.grid(column = 1, row = 2)             
    def cancel(self):
        self.remaining.destroy()
        self.bttn_3.destroy()
        self.time_state.destroy()
        self.temp1 = 0        
def countdown(self):
    if self.temp1 > 0:
        self.temp1 -= 1            
        global day_lef
        day_lef = IntVar()
        day_lef.set(int(self.temp1 / 86400))
        day_rem = self.temp1 % 86400            
        global hour_lef
        hour_lef = IntVar()
        hour_lef.set(int(day_rem / 3600))
        hour_rem = day_rem % 3600            
        global min_lef
        min_lef = IntVar()
        min_lef.set(int(hour_rem / 60))
        min_rem = hour_rem % 60            
        global sec_lef
        sec_lef = IntVar()
        sec_lef.set(int(min_rem % 60))                        
        clock.after(1000, self.countdown)                  
    else:
        self.cancel()   
def tick():
    global time1
    time2 = time.strftime('%H:%M:%S\n\n%m-%d-%Y')
    if time2 != time1:
        time1 = time2
        clock.config(text=time2)
    clock.after(200, tick)       
def grow():
    # Grow Time set window
    set_grow_time = Toplevel(app)
    set_grow_time.title("Enter Cycle Time")
    set_grow_time.geometry("240x400")
    # Set Day
    set_day_grow = Spinbox(set_grow_time, from_ = 0, to_ = 10)
    set_day_grow.grid(column = 0, row =0,
                      padx = 20, pady = 20)
    set_day_grow.config(width = 10)
    set_day_lbl = Label(set_grow_time, text = "Set Day: 0 to 10")
    set_day_lbl.grid(column = 1, row = 0)    
    # Set Hour
    set_hour_grow = Spinbox(set_grow_time, from_ = 0, to_ = 23)
    set_hour_grow.grid(column = 0, row = 1,
                       padx = 20, pady = 20)
    set_hour_grow.config(width = 10)
    set_hour_lbl = Label(set_grow_time, text = "Set Hour: 0 to 23")
    set_hour_lbl.grid(column = 1, row = 1)    
    # Set Minute
    set_min_grow = Spinbox(set_grow_time, from_ = 0, to_ = 59)
    set_min_grow.grid(column = 0, row = 2,
                      padx = 20, pady = 20)
    set_min_grow.config(width = 10)
    set_hour_lbl = Label(set_grow_time, text = "Set Minute: 0 to 59")
    set_hour_lbl.grid(column = 1, row = 2)    
    # Confirm Selection
    def fetch_time():
        global day_val
        day_val = int(set_day_grow.get())
        global hour_val 
        hour_val = int(set_hour_grow.get())
        global min_val
        min_val = int(set_min_grow.get())
        Grow_Cycle()        
    confirm_grow_time = Button(set_grow_time, text = "OK", command = lambda: (fetch_time(), set_grow_time.destroy()))
    confirm_grow_time.grid(column = 0, row = 3)
    cancel_grow_time = Button(set_grow_time, text = "Cancel", command = set_grow_time.destroy)
    cancel_grow_time.grid(column = 1, row = 3)         
def clean():
    pass # will finish later
def cancel():
    pass # will finish later       
# main
# Main Loop Begin
root = Tk()
root.title("Grower")
root.geometry("1280x720")
app = Frame(root)
app.grid()
time1 = ''
clock = Label(app)
clock.config(font = ("Impact", 20))
clock.grid(column = 1, row = 0,
           ipadx = 20, ipady = 20,
           padx = 50, pady =50)
# Button Setup
bttn_1 = Button(app, text = "Grow", command = grow)
bttn_1.configure(bg = "light green")
bttn_1.grid(column = 0, row = 0, 
            ipadx = 50, ipady = 20,
            padx = 20, pady = 100)
bttn_2 = Button(app, text = "Clean", command = clean)
bttn_2.configure(bg = "cyan")
bttn_2.grid(row = 1, column = 0, 
           ipadx = 50, ipady = 20,
           padx = 20, pady = 100)

tick()
root.mainloop()

1 个答案:

答案 0 :(得分:0)

在审核完代码后,我对您的字符串格式以及如何将字符串应用于标签进行了一些更改。

你的类def不适合我,所以我用一个标准方法重写它,用来创建一个tkinter类。

我认为您不能同时拥有text = "string'textvariable = StringVar()。所以我已经将数据格式化为你的字符串var。

你设置它的方式不会因为某些原因而起作用。你不能在textvariable中使用多个IntVar(),所以你需要先将它们组合成一个字符串变量,然后用它作为标签的更新方法。

我已更改了字符串连接,删除了+方法并使用format()代替,因为这是目前正确的方法。

我还在self.string_var.set方法中添加了countdown(),因此我们可以通过倒计时更新此内容。

请查看此代码,如果您有任何疑问,请与我们联系。

import tkinter as tk


class Grow_Cycle(tk.Frame):

    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)
        self.master = master

        self.day_val = 1
        self.hour_val = 0
        self.min_val = 0

        self.day_lef = tk.IntVar()
        self.day_lef.set(1)
        self.hour_lef = tk.IntVar()
        self.hour_lef.set(0)
        self.min_lef = tk.IntVar()
        self.min_lef.set(0)
        self.sec_lef = tk.IntVar()
        self.sec_lef.set(0)

        self.day_rem = 0
        self.hour_rem = 0
        self.min_rem = 0

        self.string_var = tk.StringVar()
        self.string_var2 = tk.StringVar()

        self.string_var.set(
            "You have remaining:\n{} days,\n{} hours,\n{} minutes,\n{} seconds".format(self.day_lef.get(), self.hour_lef.get(), self.min_lef.get(), self.sec_lef.get()))

        self.time_state = tk.Label(self.master, text = (
            "You have selected:\n {} days,\n {} hours,\n {} minutes").format(self.day_val, self.hour_val, self.min_val))
        self.time_state.grid(row = 1, column = 1)

        self.bttn_3 = tk.Button(self.master, bg = "red", text = "Cancel", command = self.cancel)
        self.bttn_3.grid(row = 2, column = 0, ipadx = 50, ipady = 20, padx = 20, pady = 100)
        self.temp1 = (self.day_val * 86400)+(self.hour_val * 3600)+(self.min_val * 60)

        self.remaining = tk.Label(self.master, textvariable = self.string_var)
        self.remaining.grid(column = 1, row = 2)

        self.countdown()

    def cancel(self):
        self.remaining.destroy()
        self.bttn_3.destroy()
        self.time_state.destroy()
        self.temp1 = 0

    def countdown(self):
        self.string_var.set(
            "You have remaining:\n{} days,\n{} hours,\n{} minutes,\n{} seconds".format(self.day_lef.get(), self.hour_lef.get(), self.min_lef.get(), self.sec_lef.get()))

        if self.temp1 > 0:
            self.temp1 -= 1

            self.day_lef.set(int(self.temp1 / 86400))
            self.day_rem = self.temp1 % 86400

            self.hour_lef.set(int(self.day_rem / 3600))
            self.hour_rem = self.day_rem % 3600

            self.min_lef.set(int(self.hour_rem / 60))
            self.min_rem = self.hour_rem % 60

            self.sec_lef.set(int(self.min_rem % 60)) 

            root.after(1000, self.countdown)                  
        else:
            self.cancel()


if __name__ == "__main__":
    root = tk.Tk()
    Grow_Cycle(root)
    root.mainloop()