Python基于tk界面的万年历+阳历阴历(附完整代码)

一.介绍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()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睡不醒的恒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值