簡體   English   中英

如何使用 tkinter 更新多個標簽

[英]How to update multiple labels with tkinter

我正在嘗試在 python 中制作一個worktime ,它還以十進制小時數顯示經過的時間作為工作時間,並將超過 8 小時的任何時間轉換為overtime

我得到了秒表部分功能(公平地說,我主要模仿教程),但是當我嘗試添加額外的小數時,事情就出錯了。 我嘗試了一堆看起來有點合乎邏輯的東西,但在運行時出現了更多錯誤,或者我的秒表旁邊的標簽保持為零,或者在目前的情況下,python 在幾秒鍾后崩潰(我的猜測是這三個.after基本上是以指數方式調用運行update() ?)

我想推土機解決方案對我來說只是為我的每個標簽復制update()函數,我 9/10 肯定它會起作用,但這聽起來很愚蠢。

import tkinter as tk

### Vars
counting = False
hours, minutes, seconds = 0, 0, 0
totalWorktime, overtime = 0, 0

### Funcs

def start():
    global counting
    if not counting:
        update()
        counting = True

def pause():
    global counting
    if counting:
        stopwatch_label.after_cancel(update_time)
        worktime_label.after_cancel(update_worktime)
        overtime_label.after_cancel(update_overtime)
        counting = False

def reset():
    global counting
    if counting:
        stopwatch_label.after_cancel(update_time)
        worktime_label.after_cancel(update_worktime)
        overtime_label.after_cancel(update_overtime)
        counting = False
    global hours, minutes, seconds, totalWorktime, overtime
    hours, minutes, seconds = 0, 0, 0
    totalWorktime, overtime = 0, 0
    stopwatch_label.config(text='00:00:00')

# update stopwatch label
def update():
    global hours, minutes, seconds, totalWorktime, overtime
    # time counting system
    seconds += 1
    if seconds ==60:
        minutes += 1
        seconds = 0
    if minutes == 60:
        hours += 1
        minutes = 0
    totalWorktime = hours + (minutes / 60)
    if totalWorktime > 8:
        overtime = totalWorktime - 8
    # format with zero padding
    hours_string = f'{hours}' if hours > 9 else f'0{hours}'
    minutes_string = f'{minutes}' if minutes > 9 else f'0{minutes}'
    seconds_string = f'{seconds}' if seconds > 9 else f'0{seconds}'
    # building label
    stopwatch_label.config(text=hours_string + ':' + minutes_string + ':' + seconds_string)
    global update_time, update_worktime, update_overtime
    update_time = stopwatch_label.after(10, update)
    update_worktime = worktime_label.after(10, update)
    update_overtime = overtime_label.after(10, update)

### UI
# main window
root = tk.Tk()
root.geometry('512x256')
root.title('Worktime Stopwatch')

# time display
stopwatch_label = tk.Label(text='00:00:00', font=('Arial', 80))
stopwatch_label.pack()
worktime_label = tk.Label(text='Work time : ' + str(totalWorktime), font=('Arial', 20))
worktime_label.pack()
overtime_label = tk.Label(text='Overtime : ' + str(overtime), font=('Arial', 20))
overtime_label.pack()

# buttons
start_button = tk.Button(text='Start', height=4, width=8, font=('Arial', 20), command=start)
start_button.pack(side=tk.LEFT)
pause_button = tk.Button(text='Pause', height=4, width=8, font=('Arial', 20), command=pause)
pause_button.pack(side=tk.LEFT)
reset_button = tk.Button(text='Reset', height=4, width=8, font=('Arial', 20), command=reset)
reset_button.pack(side=tk.LEFT)

# run
root.mainloop()

PS:是的,我知道我可以使用時間模塊,我只是喜歡腳本中簡單有趣的數學。
PS2:是的,我知道我現在的秒表計數時間太快了 100 倍,這是為了便於測試。 當它工作時,我會回到 1000 毫秒。

感謝@acw1668 的指出,我重新審視了我的代碼,並注意到我是如何誤解了.after()的用法並期望它負責刷新標簽,而它真正所做的只是調用update()以固定的間隔。

重要的部分只是上面兩行,在我的“建築標簽”評論下:

stopwatch_label.config(text=hours_string + ':' + minutes_string + ':' + seconds_string)

出於某種原因,我的大腦雖然只是將秒表標簽的不同部分合二為一。 但是.config()的核心用途恰恰是改變文本。

所以我所要做的就是把這條線復制兩次,然后改變它來影響我的工作overtime worktime

worktime_label.config(text='Work time : ' + str(totalWorktime))
overtime_label.config(text='  Overtime : ' + str(overtime))

我還必須在reset()pause()中刪除它們各自的.after_cancel()方法,並且在進行了一些更美觀的更改之后,這是整個功能代碼:

import tkinter as tk

### Vars
counting = False
hours, minutes, seconds = 0, 0, 0
totalWorktime, overtime = 0, 0

### Funcs

def start():
    global counting
    if not counting:
        update()
        counting = True

def pause():
    global counting
    if counting:
        stopwatch_label.after_cancel(update_time)
        counting = False

def reset():
    global counting
    if counting:
        stopwatch_label.after_cancel(update_time)
        counting = False
    global hours, minutes, seconds, totalWorktime, overtime
    hours, minutes, seconds = 0, 0, 0
    totalWorktime, overtime = 0, 0
    stopwatch_label.config(text='00:00:00')
    worktime_label.config(text='Work time : 0')
    overtime_label.config(text='  Overtime : 0')

# update stopwatch label
def update():
    global hours, minutes, seconds, totalWorktime, overtime
    # time counting system
    seconds += 1
    if seconds ==60:
        minutes += 1
        seconds = 0
    if minutes == 60:
        hours += 1
        minutes = 0
    totalWorktime = round(hours + (minutes / 60), 2)
    if totalWorktime > 8:
        overtime = totalWorktime - 8
    # format with zero padding
    hours_string = f'{hours}' if hours > 9 else f'0{hours}'
    minutes_string = f'{minutes}' if minutes > 9 else f'0{minutes}'
    seconds_string = f'{seconds}' if seconds > 9 else f'0{seconds}'
    # refresh labels with new text content
    stopwatch_label.config(text=hours_string + ':' + minutes_string + ':' + seconds_string)
    worktime_label.config(text='Work time : ' + str(totalWorktime))
    overtime_label.config(text='  Overtime : ' + str(overtime))
    global update_time, update_worktime, update_overtime
    update_time = stopwatch_label.after(1000, update)

### UI
# main window
root = tk.Tk()
root.geometry('512x256')
root.title('Worktime Stopwatch')

# time display
stopwatch_label = tk.Label(text='00:00:00', font=('Arial', 80))
stopwatch_label.pack()
worktime_label = tk.Label(text='Work time : 0', font=('Arial', 20), anchor="w", width=20)
worktime_label.pack()
overtime_label = tk.Label(text='  Overtime : 0', font=('Arial', 20), anchor="w", width=20)
overtime_label.pack()

# buttons
start_button = tk.Button(text='Start', height=4, width=8, font=('Arial', 20), command=start)
start_button.pack(side=tk.LEFT)
pause_button = tk.Button(text='Pause', height=4, width=8, font=('Arial', 20), command=pause)
pause_button.pack(side=tk.LEFT)
reset_button = tk.Button(text='Reset', height=4, width=8, font=('Arial', 20), command=reset)
reset_button.pack(side=tk.LEFT)

# run
root.mainloop()

謝謝您的幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM