2017-11-07 13 views
0

私はタイムクロックプログラムを書いています。私はコードを構築しましたが、その周りにGUIを作成するのに問題がありました。私は、入力を受け取り、計算のためにボタンイベント処理を行う外部関数にそれらを送るエントリーを持っています。ラベルが別の機能の変数を更新しないのはなぜですか? Tkinter

プログラムを実行すると、私は時間を更新するラベルを取得しません。私はそれが私のtextvariablesと関係があるのだろうかと思います。

from tkinter import * 
import time 
import os 


def show_entry_fields(): 
    hr= hrvar.get() 
    mn = minvar.get() 
    sc = secvar.get() 
    counter = int(hr)*3600+int(mn)*60+ int(sc) 

    mins = int(counter/60) 
    hours = int(mins/60) 

    hours = IntVar() 
    mins = IntVar() 
    secs = IntVar() 

    while counter > 0: 
     counter -= 1 
     hours, sec = divmod(counter, 3600) 
     mins, sec = divmod(sec, 60) 
     printv = StringVar() 




     printv = (" %d Hr:, %d Min: %d Sec" % (hours, mins, sec)) 
     win1 = Tk() 
     timeLabel = Label(win1, textvariable= printv).grid(row=7) 
     mins= int(counter/60) 
     hours = int(mins/60) 
     time.sleep(1) 
     os.system('cls') 
     return 
    else: 
     finishedLabel = Label(master, text="Time is Up").grid(row=7) 
     return 


    master = Tk() 
    Label(master, text="Enter Hour(s)").grid(row=0) 
    Label(master, text="Enter Mins(s)").grid(row=1) 
    Label(master, text="Enter Second(s)").grid(row=2) 

    hrvar = IntVar() 
    minvar = IntVar() 
    secvar = IntVar() 
    e1 = Entry(master, textvariable = hrvar) 
    e2 = Entry(master, textvariable = minvar) 
    e3 = Entry(master, textvariable = secvar) 

    e1.grid(row=0, column=1) 
    e2.grid(row=1, column=1) 
    e3.grid(row=2, column=1) 

    Button(master, text='Quit', command=master.quit).grid(row=3, column=0, 
    sticky=W, pady=4) 
    Button(master, text='Show', command=show_entry_fields).grid(row=3, 
    column=1, 
    sticky=W, pady=4) 

    mainloop() 

コードを更新しました。

class Timer: 

    def __init__(self, master): 
     #self.seconds = 0 
     self.time = StringVar() 
     self.hr = StringVar() 
     self.mins = StringVar() 
     self.secs = StringVar() 

     self.hr_label = Label(master, text='Enter Hours').pack() 
     self.entry_hr = Entry(master, textvariable = self.hr) 
     self.entry_hr.pack() 

     self.min_label = Label(master, text='Enter Minutes').pack() 
     self.entry_min = Entry(master, textvariable = self.mins) 
     self.entry_min.pack() 



     self.time_label = Label(master, relief='flat', font=("Cambria", 20), 
           textvariable=self.time) 
     self.set_time(hours= self.entry_hr.get(), minutes=self.entry_min.get(), seconds = 0) 

     self.time.set('00:00:00') 
     self.start_button = Button(master, text='Start') 
     self.start_button.bind('<Button-1>', self.start_countdown) 

     self.time_label.pack(padx=30, pady=10) 
     self.start_button.pack(pady=(10,20)) 

    def set_time(self, hours, minutes, seconds): 
     self.seconds = hours * 3600 + minutes * 60 + seconds 
     self.time.set(self.format_time(self.seconds)) 

    def start_countdown(self, event): 
     self.countdown() 

    def countdown(self): 
     if self.seconds <= 0: 
      return 
     self.seconds -= 1 
     self.time.set(self.format_time(self.seconds)) 
     self.time_label.after(1000, self.countdown) 

    def format_time(self, seconds): 
     h = seconds // 3600 
     m = (seconds - h*3600) // 60 
     s = seconds - h*3600 - m*60 
     return '{:0>2}:{:0>2}:{:0>2}'.format(h,m,s) 

if __name__ == '__main__': 
    root = Tk() 
    timer = Timer(root) 
    #timer.set_time(hours=0, minutes=20, seconds=0) 
    root.mainloop() 

答えて

0

コードにはいくつかの問題があります。 printvtimeLabelを再定義し、whileループのすべてのステップで新しいTk()オブジェクトを作成しています。さらに重要なことは、をStringVarと定義しますが、すぐにそれを文字列として再定義します。 whileループのの外側にを一度定義してからset()メソッドを使用してprintvを使用する必要があります。


ここはTkinterの非常に基本的なタイマーです。まず、ではなくtime.sleepまたはwhileループを使用する必要があります。 mainloop関数はすでにwhileループであり、ほとんどのtkinterオブジェクトは.after()メソッドを持ち、時間の経過後(ミリ秒単位)にイベントを呼び出すことができます。

UI全体をカプセル化するためのクラスを作成したことに注目してください。すべての変数はクラス内に格納され、メソッドから更新されます。この時間はスクリプト自体(現在は1時間20分10秒)に設定されていますが、コマンドラインやUIのテキストフィールドからargを受け入れるように変更するのは簡単です。

from tkinter import Tk, Label, StringVar 
from tkinter.ttk import Button, Entry 

class Timer: 
    def __init__(self, master): 
     self.seconds = 0 
     self.time = StringVar() 
     self.time_label = Label(master, relief='flat', font=("Cambria", 20), 
           textvariable=self.time) 

     self.hr = StringVar() 
     self.hr_label = Label(master, text='Hours:').grid(row=1, column=1, padx=5, pady=1) 
     self.entry_hr = Entry(master, textvariable=self.hr, width=4) 
     self.entry_hr.grid(row=1, column=2) 

     self.mins = StringVar() 
     self.min_label = Label(master, text='Minutes:').grid(row=2, column=1, padx=5, pady=1) 
     self.entry_min = Entry(master, textvariable=self.mins, width=4) 
     self.entry_min.grid(row=2, column=2) 

     self.secs = StringVar() 
     self.secs_label = Label(master, text='Seconds:').grid(row=3, column=1, padx=5, pady=1) 
     self.entry_sec = Entry(master, textvariable=self.secs, width=4) 
     self.entry_sec.grid(row=3, column=2) 

     self.time.set('00:00:00') 
     self.start_button = Button(master, text='Start') 
     self.start_button.bind('<Button-1>', self.start_countdown) 

     self.time_label.grid(row=0, columnspan=4, padx=30, pady=10) 
     self.start_button.grid(row=4, columnspan=4, pady=(10,20)) 

    def set_time(self, hours, minutes, seconds): 
     self.seconds = hours * 3600 + minutes * 60 + seconds 
     self.time.set(self.format_time(self.seconds)) 

    def start_countdown(self, event): 
     h = self.entry_hr.get() 
     m = self.entry_min.get() 
     s = self.entry_sec.get() 
     h,m,s = map(lambda x: int(x) if x else 0, (h,m,s)) 
     self.set_time(h,m,s) 
     self.countdown() 

    def countdown(self): 
     if self.seconds <= 0: 
      return 
     self.time.set(self.format_time(self.seconds)) 
     self.seconds -= 1 
     self.time_label.after(1000, self.countdown) 

    def format_time(self, seconds): 
     h = seconds // 3600 
     m = (seconds - h*3600) // 60 
     s = seconds - h*3600 - m*60 
     return '{:0>2}:{:0>2}:{:0>2}'.format(h,m,s) 

if __name__ == '__main__': 
    root = Tk() 
    timer = Timer(root) 
    root.mainloop() 
+0

whileループで再定義する必要がない場合、「timeLabel」はどのように使用する必要がありますか? – wonderbreadhero

+0

'timeLabel'は、表示されたテキストがオブジェクト' printv'にリンクされているLabelオブジェクトです。 'printv'を変更すると' timeLabel'に表示される値が変更されます。 – James

+0

興味深い。私は 'printv'でsetメソッドを使いましたが、私の' timeLabelは一度しか更新されません。それはLabelが 'printv'で更新していないようなものです。上記のコードを更新しました。 – wonderbreadhero

関連する問題