Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用tkinter创建计时器?_Python_User Interface_Tkinter - Fatal编程技术网

Python 如何使用tkinter创建计时器?

Python 如何使用tkinter创建计时器?,python,user-interface,tkinter,Python,User Interface,Tkinter,我需要用Python的tkinter库编写一个程序 我的主要问题是,我不知道如何创建一个计时器或类似时钟的东西 hh:mm:ss 我需要它自己更新(这是我不知道怎么做的)。Tkinter根窗口有一个名为after的方法,可以用来安排在给定时间段后调用函数。如果该函数本身在之后调用,则您已经设置了一个自动重复事件 以下是一个工作示例: # for python 3.x use 'tkinter' rather than 'Tkinter' import Tkinter as tk import t

我需要用Python的tkinter库编写一个程序

我的主要问题是,我不知道如何创建一个计时器或类似时钟的东西
hh:mm:ss


我需要它自己更新(这是我不知道怎么做的)。

Tkinter根窗口有一个名为
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()

请记住,之后的
并不能保证函数将准确地按时运行。它只安排作业在给定的时间后运行。如果应用程序正忙,在调用之前可能会有延迟,因为Tkinter是单线程的。延迟通常以微秒为单位。

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


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


这个问题我有一个简单的答案。我创建了一个线程来更新时间。在线程中,我运行一个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()
root.after(ms,func)
是您需要使用的方法。只需在主循环开始之前调用它一次,并在每次调用它时在绑定函数中重新调度它。以下是一个例子:

from tkinter import *
import time
 

def update_clock():
    timer_label.config(text=time.strftime('%H:%M:%S',time.localtime()),
                  font='Times 25')  # change the text of the time_label according to the current time
    root.after(100, update_clock)  # reschedule update_clock function to update time_label every 100 ms

root = Tk()  # create the root window
timer_label = Label(root, justify='center')  # create the label for timer
timer_label.pack()  # show the timer_label using pack geometry manager
root.after(0, update_clock)  # schedule update_clock function first call
root.mainloop()  # start the root window mainloop
从tkinter导入*
从tkinter导入消息框
root=Tk()
根几何(“400x400”)
根目录。可调整大小(0,0)
root.title(“计时器”)
秒=21
def timer():
全局秒数
如果秒数>0:
秒=秒-1
分钟=秒//60
m=str(分钟)
如果分钟<10:
m='0'+str(分钟)
se=秒-(分钟*60)
s=str(se)
如果se<10:
s='0'+str(东南)
设置时间(m+':'+s)
timer\u display.config(textvariable=time)
#在1000毫秒内再次调用此函数
root.after(1000,计时器)
elif秒数==0:
messagebox.showinfo('Message','Time is completed')
root.quit()
框架=框架(根,宽度=500,高度=500)
frames.pack()
time=StringVar()
计时器显示=标签(根,字体=('Trebuchet MS',30,'bold'))
定时器显示位置(x=145,y=100)
计时器()#启动计时器
root.mainloop()

这是一个很好的答案,但有一点很重要——显示的时间实际上是系统时间,而不是累积的错误时间(如果您等待“大约1000毫秒”60次,您得到的是“大约一分钟”而不是60秒,错误会随时间而增长)。但是-您的时钟可以跳过显示的秒数-您可以累积亚秒错误,然后向前跳过2秒。我建议:
self.after(1000-int(1000*(time.time()-int(time.time()))或1000,self.onUpdate)
。在这个表达式之前,最好将
time.time()
保存到一个变量中。我希望能够将xkcd嵌入到我的注释中:)使用frame.after()而不是root.after()的好处是什么?如果您可以添加一些描述,那会很有帮助。仅复制/粘贴代码很少有用;-)此代码给出了本地的准确时间。它还用作计时器。在我看来,最好使用“%H”而不是“%I”,因为“%I”只显示从0到12的小时数,而不显示时间是上午还是下午。或者另一种方法是同时使用“%I”和“%p”(“%p”表示AM/PM)。对自身的递归调用是否会导致“已达到python对象的最大递归次数”错误?@SatwikPasani:否,因为它不是递归调用。它只是把一个作业放在一个队列上。如何只延迟运行func一次?@user924:
self.root.after(delay,func)
。这段代码有很多问题。update()函数中的while循环是一个繁忙的循环。从多个线程访问全局变量time_标签并不好,但我觉得这是最好的方法。因为这不会降低应用程序的性能。。。。只是一个旁注,
之后的
是一个,因此也可以在
计时器标签上调用它。
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()
from tkinter import *
import time
 

def update_clock():
    timer_label.config(text=time.strftime('%H:%M:%S',time.localtime()),
                  font='Times 25')  # change the text of the time_label according to the current time
    root.after(100, update_clock)  # reschedule update_clock function to update time_label every 100 ms

root = Tk()  # create the root window
timer_label = Label(root, justify='center')  # create the label for timer
timer_label.pack()  # show the timer_label using pack geometry manager
root.after(0, update_clock)  # schedule update_clock function first call
root.mainloop()  # start the root window mainloop
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()