如何在tkinter中安排更新(f/e,以更新时钟)?

8tntrjer  于 2022-10-22  发布在  Python
关注(0)|答案(8)|浏览(142)

我正在用Python的tkinter库编写一个程序。
我的主要问题是我不知道如何创建像hh:mm:ss这样的计时器时钟
我需要它自己更新(这是我不知道该怎么做的);当我在循环中使用time.sleep()时,整个GUI都会冻结。

hjzp0vay

hjzp0vay1#

Tkinter根窗口有一个名为after的方法,可用于调度在给定时间段后调用的函数。如果该函数本身调用after,则设置了一个自动循环事件。
下面是一个工作示例:


# for python 3.x use 'tkinter' rather than 'Tkinter'

import Tkinter as tk
import time

class App():
    def __init__(self):
        self.root = tk.Tk()
        self.label = tk.Label(text="")
        self.label.pack()
        self.update_clock()
        self.root.mainloop()

    def update_clock(self):
        now = time.strftime("%H:%M:%S")
        self.label.configure(text=now)
        self.root.after(1000, self.update_clock)

app=App()

请记住,after并不能保证函数会准时运行。它仅计划在给定时间段后运行作业。如果应用程序正忙,则在调用之前可能会有延迟,因为Tkinter是单线程的。延迟通常以微秒为单位测量。

8mmmxcuj

8mmmxcuj2#

使用框架的Python3时钟示例。after()而不是顶级应用程序。还显示了使用StringVar()更新标签


# !/usr/bin/env python3

# Display UTC.

# started with https://docs.python.org/3.4/library/tkinter.html#module-tkinter

import tkinter as tk
import time

def current_iso8601():
    """Get current date and time in ISO8601"""
    # https://en.wikipedia.org/wiki/ISO_8601
    # https://xkcd.com/1179/
    return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        self.now = tk.StringVar()
        self.time = tk.Label(self, font=('Helvetica', 24))
        self.time.pack(side="top")
        self.time["textvariable"] = self.now

        self.QUIT = tk.Button(self, text="QUIT", fg="red",
                                            command=root.destroy)
        self.QUIT.pack(side="bottom")

        # initial time display
        self.onUpdate()

    def onUpdate(self):
        # update displayed time
        self.now.set(current_iso8601())
        # schedule timer to call myself after 1 second
        self.after(1000, self.onUpdate)

root = tk.Tk()
app = Application(master=root)
root.mainloop()
c3frrgcw

c3frrgcw3#

from tkinter import *
import time
tk=Tk()
def clock():
    t=time.strftime('%I:%M:%S',time.localtime())
    if t!='':
        label1.config(text=t,font='times 25')
    tk.after(100,clock)
label1=Label(tk,justify='center')
label1.pack()
clock()
tk.mainloop()
5m1hhzi4

5m1hhzi44#

您应该在main循环之前调用.after_idle(callback),在callback函数的末尾调用m1n 1o1p。
例子:

import tkinter as tk
import time

def refresh_clock():
    clock_label.config(
        text=time.strftime("%H:%M:%S", time.localtime())
    )
    root.after(1000, refresh_clock)  # <--

root = tk.Tk()

clock_label = tk.Label(root, font="Times 25", justify="center")
clock_label.pack()

root.after_idle(refresh_clock)  # <--
root.mainloop()
sqserrrh

sqserrrh5#

我对这个问题有一个简单的答案。我创建了一个线程来更新时间。在线程中,我运行一个while循环,获取时间并更新它。检查下面的代码,不要忘记将其标记为正确答案。

from tkinter import *
from tkinter import *
import _thread
import time

def update():
    while True:
      t=time.strftime('%I:%M:%S',time.localtime())
      time_label['text'] = t

win = Tk()
win.geometry('200x200')

time_label = Label(win, text='0:0:0', font=('',15))
time_label.pack()

_thread.start_new_thread(update,())

win.mainloop()
zf9nrax1

zf9nrax16#

我刚刚使用MVP模式创建了一个简单的计时器(但是对于这个简单的项目来说,这可能太过分了)。它有退出、开始/暂停和停止按钮。时间以HH:MM:SS格式显示。使用每秒运行几次的线程以及计时器启动时间和当前时间之间的差来实现时间计数。
Source code on github

f3temu5u

f3temu5u7#

from tkinter import *

from tkinter import messagebox

root = Tk()

root.geometry("400x400")

root.resizable(0, 0)

root.title("Timer")

seconds = 21

def timer():

    global seconds
    if seconds > 0:
        seconds = seconds - 1
        mins = seconds // 60
        m = str(mins)

        if mins < 10:
            m = '0' + str(mins)
        se = seconds - (mins * 60)
        s = str(se)

        if se < 10:
            s = '0' + str(se)
        time.set(m + ':' + s)
        timer_display.config(textvariable=time)
        # call this function again in 1,000 milliseconds
        root.after(1000, timer)

    elif seconds == 0:
        messagebox.showinfo('Message', 'Time is completed')
        root.quit()

frames = Frame(root, width=500, height=500)

frames.pack()

time = StringVar()

timer_display = Label(root, font=('Trebuchet MS', 30, 'bold'))

timer_display.place(x=145, y=100)

timer()  # start the timer

root.mainloop()
zpf6vheq

zpf6vheq8#

您可以在tkinter中对此进行emulate time.sleep,并在给定时间后调用该函数。这可能会增加代码的可读性:

import tkinter as tk
import time

def tksleep(t):
    'emulating time.sleep(seconds)'
    ms = int(t*1000)
    root = tk._get_default_root()
    var = tk.IntVar(root)
    root.after(ms, lambda: var.set(1))
    root.wait_variable(var)

def tick():
    clock.configure(text=time.strftime("%H:%M:%S"))
    tksleep(0.25) #sleep for 0.25 seconds
    tick() #run tick again

root = tk.Tk()
clock = tk.Label(root,text='5')
clock.pack(fill=tk.BOTH,expand=True)
tick()
root.mainloop()

相关问题