一.介绍tkinter并下载
-
tkinter
tkinter(Tk interface)是Python的标准GUl库,支持跨平台的GUl程序开发。tkinter适合小型的GUl程序编写,也特别适合初学者学习GUl编程。
具体运用理解请看python --Tkinter详解
下面是一些常用的语法知识:
cmd-->输入:pip install tkinter 进行下载
二.具体实现
我将具体按照以下步骤实现最终目的:
1. 用户打开程序,界面显示当前日期的阳历和农历日期。
2. 用户可以选择年、月和日,并点击“更新日历”按钮来更新日历。
3. 程序根据用户选择的日期计算出当月的天数和每一天对应的星期几。
4. 程序在界面上显示当前月份的所有日期,以及它们对应的星期几和农历日期。
5. 用户可以继续选择不同的日期并更新日历,直到退出程序。
2.1 导入模块
from tkinter import *
import time
from zhdate import ZhDate as lunar_date
from datetime import datetime
2.2 具体函数构建
class Calendar:
def __init__(self):
self.vYear = StringVar()
self.vMonth = StringVar()
self.vDay = StringVar()
self.vNongLi = StringVar()
def leap_year(self,year):
#判断是否为闰年
if (year %400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
return True
else:
return False
def year_days(self,year,month): #计算本月天数
if month in (1,3,5,7,8,10,12):
return 31
elif month in (4,6,9,11):
return 30
else:
if self.leap_year(year)==True:
return 29
else:
return 28
def get_total_days(self,year,month,day):
total_days=0
for m in range(1800,year):
if self.leap_year(m)==True:
total_days+=366
else:
total_days+=365
for i in range(1,month):
total_days+=self.year_days(year,i)
return total_days
def calcFirstDayOfMonth(self,year,month,day):
#返回当月1日是星期几,由1800.01.01是星期三推算
return(self.get_total_days(year,month,day)+3)%7
def createMonth(self,master):
#创建日历
for i in range(6):
for j in range(7):
Label(master,text='').grid(row = i + 2,column = j)
#更新日历
def updateDate(self):
#得到当前选择的日期
year = int(self.vYear.get())
month = int(self.vMonth.get())
day = int(self.vDay.get())
fd = self.calcFirstDayOfMonth(year,month,1)
dt_date2 = datetime(year, month, day) # python自带的阳历date类型
# print(dt_date2) # 2020-08-25 00:00:00
date2 = lunar_date.from_datetime(dt_date2) # 农历2020年7月7日 , 从阳历日期转换成农历日期
self.vNongLi.set(str(date2))
for i in range(6):
for j in range(7):
#返回 grid 中 (i +2,j)位置的组件
root.grid_slaves(i +2,j)[0]['text'] = ''
#计算本月的天数
days=self.year_days(year,month)
for i in range(1,days + 1):
root.grid_slaves(int((i + fd - 1)//7 + 2),(i + fd -1)%7)[0]['text'] = str(i)
Label(root,textvariable=self.vNongLi).grid(row=0,column=7)
def drawHeader(self,master):
'''添加日历头'''
#得到当前的日期,设置为默认值
now = time.localtime(time.time())
col_idx = 0
#创建年份组件
self.vYear = StringVar()
self.vYear.set(now[0])
Label(master,text = '年').grid(row = 0,column = col_idx);col_idx += 1
#设置年份可选菜单OptionMenu项,OptionMenu功能与combox相似
omYear = OptionMenu(master,self.vYear,*tuple(range(1900,2051)))
omYear.grid(row = 0,column = col_idx);col_idx += 1
#创建月份组件
self.vMonth.set(now[1])
Label(master,text = '月').grid(row = 0,column = col_idx);col_idx += 1
#设置月份可选菜单OptionMenu项
omMonth = OptionMenu(master,self.vMonth,*tuple(range(1,13)))
omMonth.grid(row = 0,column = col_idx);col_idx += 1
#创建日组件
self.vDay.set(now[2])
Label(master,text = '日').grid(row = 0,column = col_idx);col_idx +=1
#设置日可选菜单OptionMenu项
omDay = OptionMenu(master,self.vDay,*tuple(range(1,32)))
omDay.grid(row = 0,column = col_idx);col_idx += 1
#创建更新按钮
btUpdate=Button(master,text = '更新日历',command = self.updateDate)
btUpdate.grid(row = 0,column = col_idx);col_idx += 1
#打印星期标签
weeks = ['周日','周一','周二','周三','周四','周五','周六']
for week in weeks:
Label(master,text = week).grid(row = 1,column = weeks.index(week))
Label(master, textvariable=self.vNongLi).grid(row=0, column=len(weeks))
在这其中,我们运用了这些具体函数来完成功能
1. leap_year(year): 判断是否为闰年,如果是闰年返回True,否则返回False。
2. year_days(year, month): 计算某一年某一月的天数,返回天数。
3. get_total_days(year, month, day): 计算从1800年1月1日到某一年某一月某一日的总天数,返回总天数。
4. calcFirstDayOfMonth(year, month, day): 计算某一年某一月1日是星期几,返回星期几。
5. createMonth(master): 创建日历界面,将每一天的日期显示在对应的位置上。
6. updateDate(): 更新日历界面,根据用户选择的日期计算出当月的天数和每一天对应的星期几,并在界面上显示出来。
7. drawHeader(master): 创建日历头,包括年、月、日的选择菜单和更新按钮,以及星期标签和农历日期的显示。
三.最终效果
大家可以自己调整代码,构建一个自己喜欢的万年历!
四.完整代码
from tkinter import *
import time
from zhdate import ZhDate as lunar_date
from datetime import datetime
class Calendar:
def __init__(self):
self.vYear = StringVar()
self.vMonth = StringVar()
self.vDay = StringVar()
self.vNongLi = StringVar()
def leap_year(self,year):
#判断是否为闰年
if (year %400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
return True
else:
return False
def year_days(self,year,month): #计算本月天数
if month in (1,3,5,7,8,10,12):
return 31
elif month in (4,6,9,11):
return 30
else:
if self.leap_year(year)==True:
return 29
else:
return 28
def get_total_days(self,year,month,day):
total_days=0
for m in range(1800,year):
if self.leap_year(m)==True:
total_days+=366
else:
total_days+=365
for i in range(1,month):
total_days+=self.year_days(year,i)
return total_days
def calcFirstDayOfMonth(self,year,month,day):
#返回当月1日是星期几,由1800.01.01是星期三推算
return(self.get_total_days(year,month,day)+3)%7
def createMonth(self,master):
#创建日历
for i in range(6):
for j in range(7):
Label(master,text='').grid(row = i + 2,column = j)
#更新日历
def updateDate(self):
#得到当前选择的日期
year = int(self.vYear.get())
month = int(self.vMonth.get())
day = int(self.vDay.get())
fd = self.calcFirstDayOfMonth(year,month,1)
dt_date2 = datetime(year, month, day) # python自带的阳历date类型
# print(dt_date2) # 2020-08-25 00:00:00
date2 = lunar_date.from_datetime(dt_date2) # 农历2020年7月7日 , 从阳历日期转换成农历日期
self.vNongLi.set(str(date2))
for i in range(6):
for j in range(7):
#返回 grid 中 (i +2,j)位置的组件
root.grid_slaves(i +2,j)[0]['text'] = ''
#计算本月的天数
days=self.year_days(year,month)
for i in range(1,days + 1):
root.grid_slaves(int((i + fd - 1)//7 + 2),(i + fd -1)%7)[0]['text'] = str(i)
Label(root,textvariable=self.vNongLi).grid(row=0,column=7)
def drawHeader(self,master):
'''添加日历头'''
#得到当前的日期,设置为默认值
now = time.localtime(time.time())
col_idx = 0
#创建年份组件
self.vYear = StringVar()
self.vYear.set(now[0])
Label(master,text = '年').grid(row = 0,column = col_idx);col_idx += 1
#设置年份可选菜单OptionMenu项,OptionMenu功能与combox相似
omYear = OptionMenu(master,self.vYear,*tuple(range(1900,2051)))
omYear.grid(row = 0,column = col_idx);col_idx += 1
#创建月份组件
self.vMonth.set(now[1])
Label(master,text = '月').grid(row = 0,column = col_idx);col_idx += 1
#设置月份可选菜单OptionMenu项
omMonth = OptionMenu(master,self.vMonth,*tuple(range(1,13)))
omMonth.grid(row = 0,column = col_idx);col_idx += 1
#创建日组件
self.vDay.set(now[2])
Label(master,text = '日').grid(row = 0,column = col_idx);col_idx +=1
#设置日可选菜单OptionMenu项
omDay = OptionMenu(master,self.vDay,*tuple(range(1,32)))
omDay.grid(row = 0,column = col_idx);col_idx += 1
#创建更新按钮
btUpdate=Button(master,text = '更新日历',command = self.updateDate)
btUpdate.grid(row = 0,column = col_idx);col_idx += 1
#打印星期标签
weeks = ['周日','周一','周二','周三','周四','周五','周六']
for week in weeks:
Label(master,text = week).grid(row = 1,column = weeks.index(week))
Label(master, textvariable=self.vNongLi).grid(row=0, column=len(weeks))
root = Tk()
root.title("万年历")
AppCal=Calendar()
AppCal.drawHeader(root)
AppCal.createMonth(root)
AppCal.updateDate()
root.mainloop()