聊聊Python中的GUI布局Tkinter
現(xiàn)在極少有人會(huì)用上tkinter了,所以真正研究的人也就更少了,本來不想更新tkinter。看到很多人在學(xué)tkinter,其實(shí)用Python做布局,沒有人這么干。但還是更新幾節(jié)tkinter,在Python從入門到大師教程中來。
tkinter
Tkinter包是Python附帶的標(biāo)準(zhǔn)軟件包,所以我們不需要安裝任何東西就可以使用它。
窗口主體框架
每一個(gè) tkinter 應(yīng)用的主體框架都可以包含下面這部分. 定義 window 窗口 和 window的一些屬性, 然后書寫窗口內(nèi)容, 最后執(zhí)行window.mainloop讓窗口活起來.
- import tkinter as tk
- window = tk.Tk()
- window.title('my window')
- window.geometry('200x100')
- # 這里是窗口的內(nèi)容
- window.mainloop()
窗口內(nèi)容
這次我們會(huì)建立一個(gè)用來描述的標(biāo)簽 tk.Label, 比如:
- import tkinter as tk
- window = tk.Tk()
- window.title('my window')
- window.geometry('200x100')
- l = tk.Label(window,
- text='OMG! this is TK!', # 標(biāo)簽的文字
- bg='green', # 背景顏色
- font=('Arial', 12), # 字體和字體大小
- width=15, height=2 # 標(biāo)簽長寬
- )
- l.pack() # 固定窗口位置
- window.mainloop()
控件
上面的Label就是一個(gè)控件,還有很多的,如按鈕,標(biāo)簽和文本框等,如下圖所示

控件自帶的共同屬性,如大小,字體和顏色等??筛鶕?jù)控件展現(xiàn)形式選擇相應(yīng)的屬性,具體屬性如下表:

tkinter綁定事件
tkinter綁定事件,就是定義一個(gè)函數(shù),然后通過command屬性傳入函數(shù)名,下面通過Button綁定事件,點(diǎn)擊就出現(xiàn)Runsen愛學(xué)習(xí)
- from tkinter import *
- def p_label():
- global root
- Lb = Label(root, text='Runsen愛學(xué)習(xí)')
- Lb.pack()
- root = Tk()
- root.title("應(yīng)用程序窗口")
- B_n = Button(root, text='點(diǎn)我', command=p_label, bg='red') # command后面不能有任何的標(biāo)點(diǎn)符號(hào)
- B_n.pack()
- root.mainloop()
布局顯示
一個(gè)窗口都應(yīng)該有布局,就是pack的時(shí)候需要設(shè)置side,expand需要擴(kuò)展嗎,fill需要填充嗎
- from tkinter import *
- root = Tk()
- root.title("應(yīng)用程序窗口")
- Button(root,text='1').pack(side=LEFT,expand=YES,fill=Y)
- Button(root,text='2').pack(side=TOP,expand=YES,fill=BOTH)
- Button(root,text='3').pack(side=RIGHT,expand=YES,fill=NONE)
- Button(root,text='4').pack(side=LEFT,expand=NO,fill=Y)
- Button(root,text='5').pack(side=TOP,expand=YES,fill=BOTH)
- Button(root,text='6').pack(side=BOTTOM,expand=YES)
- Button(root,text='7').pack(anchor=SE)
- root.mainloop()
除了pack還有一個(gè)grid,grid將組件布局為表格
下面做一個(gè)電話撥號(hào)盤GUI
- from tkinter import *
- root = Tk()
- labels = [['1','2','3'], # 文本,布局為網(wǎng)格
- ['4','5','6'],
- ['7','8','9'],
- ['*','0','#']]
- for r in range(4): # 行循環(huán)
- for c in range(3): # 列循環(huán)
- label = Label(root,
- relief=RAISED, # 設(shè)置邊框格式
- padx=10, # 加寬標(biāo)簽
- text=labels[r][c]) # 標(biāo)簽文本
- label.grid(row=r, column=c) # 將標(biāo)簽放置在r行c列
- root.mainloop()
制作一個(gè)日歷
上面教你做一個(gè)電話撥號(hào)盤GUI,下面能做一個(gè)簡單的日歷嗎?
我看你就不會(huì),不是我瞧不起你
放心,有我在。這需要導(dǎo)入calendar模塊了,

- import calendar
- from tkinter import *
- root = Tk()
- labels = [['Mon','Tue','Wed','Thu','Fri','Sat','Sun']]
- MonthCal = calendar.monthcalendar(2020, 5)
- 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()
豐富我們的日歷
上面的日歷就是一個(gè)辣雞,啥功能都沒有,需求很簡單,就是來兩個(gè)按鈕實(shí)現(xiàn)向上翻,向下翻。
向上翻,向下翻兩個(gè)按鈕就需要清空界面,再把日歷加到labels列表中 ,放置日歷。好像很簡單,其實(shí)就是這么簡單。
大家想一想,怎么做出來。我還是給標(biāo)準(zhǔn)實(shí)現(xiàn)代碼
- # @Author:Runsen
- 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列表:放置“星期”的標(biāo)題
- labels = [['Mon','Tue','Wed','Thu','Fri','Sat','Sun']]
- # 用calendar庫計(jì)算日歷
- 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) # 網(wǎng)格布局
- # 默認(rèn)日期
- Year, Month = 2020,5
- 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)+3, 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)+3, column=6)
- root.mainloop()
運(yùn)行一波,來一個(gè)最終實(shí)現(xiàn)gif效果圖。