如何获得带有动态标签的滴答计时器?

时间:2018-08-05 13:55:17

标签: python-2.7 tkinter

即时通讯试图做的是,每当光标在标签上时,它都必须显示经过的时间,因为它在创建时通过减去(def on_enter(i))值可以很好地实现,但是我希望它在光标处于仍在标签上。

我尝试将after函数用作新手,但我不太理解在动态标签上使用它。

任何帮助将不胜感激

代码:

from Tkinter import *

import datetime
date  = datetime.datetime
now = date.now()

master=Tk()

list_label=[]
k=[]

time_var=[]
result=[]
names=[]

def delete(i):
    k[i]=max(k)+1
    time_var[i]='<deleted>'
    list_label[i].pack_forget()

def create():#new func
    i=k.index(max(k))

    for j in range(i+1,len(k)):
        if k[j]==0:
            list_label[j].pack_forget()

    list_label[i].pack(anchor='w')

    time_var[i]=time_now()

    for j in range(i+1,len(k)):
        if k[j]==0:
            list_label[j].pack(anchor='w')

    k[i]=0
###########################
def on_enter(i):
    list_label[i].configure(text=time_now()-time_var[i])

def on_leave(i):
    list_label[i].configure(text=names[i])

def time_now():
    now = date.now()
    return date(now.year,now.month,now.day,now.hour,now.minute,now.second)
############################

for i in range(11):
    lb=Label(text=str(i),anchor=W)
    list_label.append(lb)
    lb.pack(anchor='w')
    lb.bind("<Button-3>",lambda event,i=i:delete(i))
    k.append(0)
    names.append(str(i))

    lb.bind("<Enter>",lambda event,i=i: on_enter(i))
    lb.bind("<Leave>",lambda event,i=i: on_leave(i))
    time_var.append(time_now())

master.bind("<Control-Key-z>",lambda event: create())
mainloop()

1 个答案:

答案 0 :(得分:0)

您将像这样使用after

###########################
def on_enter(i):
    list_label[i].configure(text=time_now()-time_var[i])
    list_label[i].timer = list_label[i].after(1000, on_enter, i)

def on_leave(i):
    list_label[i].configure(text=names[i])
    list_label[i].after_cancel(list_label[i].timer)

但是,您在这里的方法是完全错误的。您目前有一些功能和数据列表。您应该做的是使包含功能和数据在一起的单个对象,并列出这些功能和数据。这样,您可以为单个Label编写代码,然后重复该代码。它使您的代码简单得多,部分原因是您不再需要跟踪“ i”。像这样:

import Tkinter as tk
from datetime import datetime

def time_now():
    now = datetime.now()
    return datetime(now.year,now.month,now.day,now.hour,now.minute,now.second)

class Kiran(tk.Label):
    """A new type of Label that shows the time since creation when the mouse hovers"""
    hidden = []
    def __init__(self, master=None, **kwargs):
        tk.Label.__init__(self, master, **kwargs)
        self.name = self['text']
        self.time_var = time_now()
        self.bind("<Enter>", self.on_enter)
        self.bind("<Leave>", self.on_leave)
        self.bind("<Button-3>", self.hide)

    def on_enter(self, event=None):
        self.configure(text=time_now()-self.time_var)
        self.timer = self.after(1000, self.on_enter)

    def on_leave(self, event=None):
        self.after_cancel(self.timer) # cancel the timer
        self.configure(text=self.name)

    def hide(self, event=None):
        self.pack_forget()
        self.hidden.append(self) # add this instance to the list of hidden instances

    def show(self):
        self.time_var = time_now() # reset time
        self.pack(anchor='w')

def undo(event=None):
    '''if there's any hidden Labels, show one'''
    if Kiran.hidden:
        Kiran.hidden.pop().show()

def main():
    root = tk.Tk()
    root.geometry('200x200')
    for i in range(11):
        lb=Kiran(text=i)
        lb.pack(anchor='w')
    root.bind("<Control-Key-z>",undo)
    root.mainloop()

if __name__ == '__main__':
    main()

更多说明:

  • 除非被迫使用,否则请勿使用lambda;已知会导致错误。
  • 请勿使用通配符导入(from module import *),它们会导致错误并违反PEP8。
  • 将所有内容放入函数中。
  • 使用描述性长名称。单字母名称只会浪费时间。将名称视为微小的注释。
  • 在您的代码中添加更多注释,以便其他人不必猜测代码应该做什么。
  • 尝试一个面向初学者的论坛,以解决诸如此类的问题,例如Learnpython.reddit.com