Tkinter入门:制作一个日历

写在前面的话

Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口。Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。——摘自菜鸟教程
官网地址:https://docs.python.org/zh-cn/3.8/library/tkinter.html
本文参考:《程序设计导论:Python计算与应用开发实践》

原文链接:https://blog.zhaojingyi0126.com/#/Python/28

今日目标:制作一个日历界面

动态效果如下

需要用到的组件:Label(显示文本)、gird(布局为网格)、Button(按钮)

具体拆分一下就是:
日历部分的数字,需要用Label来显示
日期怎么放置,由gird控制
NextPrevious需要由Button来控制

下面会详细介绍一下这三个组件。觉得麻烦的同学,可以直接拖到最后看日历代码~

1 GUI窗口

image
from tkinter import * # 导入类,Python标准库,无需安装
root = Tk() # 实例化对象
root.mainloop() # 显示窗口

2 Label组件

2.1 显示文本

from tkinter import *
root = Tk()
hello = Label(master = root, text = "Hello GUI world!") # 创建Label对象
hello.pack() # 放置于父组件的顶部中心
root.mainloop()

2.2 显示图像

from tkinter import *
root = Tk()
photo = PhotoImage(file='cake.png') # 将图片转化为tkinter可以显示的格式
hello = Label(master=root,
              image=photo,
              width=300, # 标签宽度,以像素为单位
              height=180) # 标签高度,以像素为单位
hello.pack()
root.mainloop()

3 布局组件

3.1 pack

from tkinter import *
root = Tk()
text = Label(root,
             font=('Helvetica',16,'bold italic'), # 设置字体,加粗、斜体、大小16点
             width=20,             
             foreground='white', # 字体颜色
             background='black', # 背景颜色
             padx=25, # 标签左右扩展25像素
             pady=10, # 标签上下扩展10像素
             text='This is my painting.')
text.pack(side=BOTTOM) # 标签放在下方

cake = PhotoImage(file='cake.png')
cakeLabel = Label(root,
                  image=cake, 
                  background='white', 
                  width=150,
                  height=150,
                  borderwidth=3, # 设置标签边框宽度
                  relief=RIDGE) # 设置标签边框样式:隆起
cakeLabel.pack(side=LEFT) # 标签放在左侧

melon = PhotoImage(file='watermelon.png')
melonLabel = Label(root,
                   background='white', 
                   width=150,
                   height=150,
                   image=melon)
melonLabel.pack(side=RIGHT) # 标签放在右侧

root.mainloop()
from tkinter import *
root = Tk()
text = Label(root,
             font=('Helvetica',16,'bold italic'), # 设置字体,加粗、斜体、大小16点                
             foreground='white', # 字体颜色
             background='black', # 背景颜色
             padx=25, # 标签左右扩展25像素
             pady=50, # 标签上下扩展10像素
             text='This is my painting.\n It is a cake.')
text.pack(side=LEFT) # 标签放在下方

cake = PhotoImage(file='cake.png')
cakeLabel = Label(root,
                  image=cake, 
                  background='white', 
                  width=150,
                  height=150,
                  borderwidth=3, # 设置标签边框宽度
                  relief=RIDGE) # 设置标签边框样式:隆起
cakeLabel.pack(side=RIGHT) # 标签放在左侧

root.mainloop()

3.2 grid

grid将组件布局为表格

电话拨号盘GUI

from tkinter import *
root = Tk()
labels = [['1','2','3'], # 文本,布局为网格
          ['4','5','6'],
          ['7','8','9'],
          ['*','0','#']]

for r in range(4): # 行循环
    for c in range(3): # 列循环
        label = Label(root,
                      relief=RAISED, # 设置边框格式
                      padx=10, # 加宽标签
                      text=labels[r][c]) # 标签文本
        label.grid(row=r, column=c) # 将标签放置在r行c列

root.mainloop()

GUI:根据输入的年份和月份,自动生成日历

import calendar 
from tkinter import *
root = Tk()
labels = [['Mon','Tue','Wed','Thu','Fri','Sat','Sun']]
MonthCal = calendar.monthcalendar(2020, 3)
for i in range(len(MonthCal)):
    labels.append(MonthCal[i])
for r in range(len(MonthCal)+1):
    for c in range(7):
        if labels[r][c] == 0:
            labels[r][c] = ' '
        label = Label(root,          
                      padx=5,
                      pady=5,
                      text=str(labels[r][c]))        
        label.grid(row=r,column=c)
root.mainloop()

4 Button组件

GUI:点击Click it,显示当前时间

from tkinter import *
from tkinter.messagebox import showinfo
import datetime

def clicked():
    day = datetime.datetime.now().strftime('%d %b %Y')
    time = datetime.datetime.now().strftime('%H:%M:%S %p')
    text = 'Day:'+day+'\n'+'Time:'+time+'\n'
    showinfo(message=text)

root = Tk()

botton = Button(root,
                text='Click it',
                command=clicked)
botton.pack()
root.mainloop()

5 制作日历

import calendar 
from tkinter import *
root = Tk()

def LabelCal(Year, Month):
    # 首行放置“年、月”的位置
    label = Label(root,text=str(Year)+"年")
    label.grid(row=0,column=2)
    label = Label(root,text=str(Month)+"月")
    label.grid(row=0,column=4)
    # labels列表:放置“星期”的标题
    labels = [['Mon','Tue','Wed','Thu','Fri','Sat','Sun']]
    # 用calendar库计算日历
    MonthCal = calendar.monthcalendar(Year, Month)
    # 先把界面清空
    for r in range(7):
        for c in range(7):            
            label = Label(root,
                          width =5,
                          padx=5,
                          pady=5,
                          text=' ')        
            label.grid(row=r+1,column=c)
    # 把日历加到labels列表中     
    for i in range(len(MonthCal)):
        labels.append(MonthCal[i])
    # 放置日历
    for r in range(len(MonthCal)+1):
        for c in range(7):
            if labels[r][c] == 0:
                labels[r][c] = ' '
            label = Label(root,
                          width =5,
                          padx=5,
                          pady=5,
                          text=str(labels[r][c]))        
            label.grid(row=r+1,column=c) # 网格布局

# 默认日期
Year, Month = 2020,3
LabelCal(Year, Month)

# button:Enter
def ButtonPrevious():
    global Year, Month
    Month = Month-1
    if Month<1:
        Month = Month+12
        Year = Year-1
    LabelCal(Year, Month)

button1 = Button(root, text='Previous', command=ButtonPrevious)
button1.grid(row=len(MonthCal)+2, column=0)

# button:Clear
def ButtonNext():
    global Year, Month
    Month = Month+1
    if Month>12:
        Month = Month-12
        Year = Year+1 
    LabelCal(Year, Month)

button2 = Button(root, text='Next', command=ButtonNext)
button2.grid(row=len(MonthCal)+2, column=6)

root.mainloop()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容