在手机和计算机上,都有一个“闹钟和时钟”程序,包括秒表、计时器、闹钟和时钟4个功能。如果使用python设计这个“闹钟和时钟”程序,需解决以下3个问题。第1,秒表、计时器、闹钟和时钟4个功能每1秒都要改变显示的时间。如在主程序建立一个死循环,死循环首先延迟1秒,改变4个功能显示时间后,进入下一次循环,这显然不是一个好方法。比较好的方法是在另一线程建立秒计时器,每隔1秒发一个自定义事件,秒表、计时器、闹钟和时钟响应这个自定义事件,改变自己时间。下边是实现代码。如将第5条语句中的isTime改为true,注释掉第20条语句,运行后再用单击窗体右上角的X按钮关闭窗体将报错,意思是主程序已结束不再接收事件,仍发自定义事件。因此第20条语句将窗口关闭事件函数设定为closeRoot,包括单击窗体右上角的X按钮关闭窗体,在函数closeRoot中使isTime=False,在关闭窗体前,使子线程结束,避免报错。
from threading import Timer
import time
import tkinter as tk
def hello():
while isTime: #isTime=False,使子线程结束
root.event_generate('<<myEvent>>')#发送自定义事件myEvent
time.sleep(1)
def myEventFun(event): #自定义事件myEvent事件函数
global n
n+=1
label['text']=str(n) #显示秒数
def closeRoot(): #关闭窗体事件函数
isTime=False #在关闭窗体前,isTime=False,使子线程结束
root.quit()
root = tk.Tk()
root.title('自定义事件')
root.geometry('300x250')
root.resizable(width=False,height=False)
root.bind("<<myEvent>>",myEventFun) #将事件和事件函数绑定
#将窗口关闭事件函数设定为closeRoot,包括单击窗体右上角的X按钮关闭窗体
root.protocol("WM_DELETE_WINDOW",closeRoot)
n=0
isTime=True
label=tk.Label(root,fg='red',font=("Arial",15))
label.place(x=20,y=10,width=250,height=40)
t = Timer(1, hello) #建立Timer类对象,1秒后将调用函数hello()在子线程中运行
t.setDaemon(True) #使主进程结束后子线程也会随之结束。
t.start() #启动子线程
root.mainloop()
第2,秒表、计时器、闹钟和时钟4个功能界面在不同容器中,一次只能观察一个界面,可用标签选择不同界面,可用ttk.Notebook组件实现。下边是实现代码。
import tkinter as tk #装载tkinter模块,用于Python3
from tkinter import ttk #装载tkinter.ttk模块,用于Python3
root =tk.Tk() # 创建窗口对象
root.title('闹钟和时钟') #设置窗口标题
root.geometry('400x300+200+200')
root.resizable(width=False,height=False) #设置窗口是否可变,宽不可变,高不可变,默认为True
ttk.Style().configure(".", font=("仿宋", 20))
tabControl = ttk.Notebook(root) #创建Notebook
tab1 = tk.Frame(tabControl,bg='blue') #增加新选项卡
tabControl.add(tab1, text='闹钟') #把新选项卡增加到Notebook
tab2 = tk.Frame(tabControl,bg='yellow')
tabControl.add(tab2, text='时钟')
tab3 = tk.Frame(tabControl,bg='green')
tabControl.add(tab3, text='计时器')
tab4 = tk.Frame(tabControl,bg='blue')
tabControl.add(tab4, text='秒表')
tabControl.pack(expand=1, fill="both")
tabControl.select(tab1) #选择tab1
root.mainloop() # 进入消息循环
'''
如要将每个默认按钮更改为具有一些填充和不同背景颜色的平面按钮:
from tkinter import ttk
import tkinter
root = tkinter.Tk()
ttk.Style().configure("TButton", padding=6, relief="flat",
background="#ccc")
btn = ttk.Button(text="Sample")
btn.pack()
'''
第3,计时器和闹钟时间到后,要用声音提醒,发生可用如下代码。另外博文“python tkinter Tix.Control使用”中介绍的组件Tix.Control也准备用到“闹钟和时钟”程序中。
import winsound
winsound.Beep(600,1000)
#其中600表示声音大小,1000表示发生时长,1000为1秒