四十八、Python中的GUI布局tkinter
「@Author:Runsen」
現(xiàn)在極少有人會用上tkinter了,所以真正研究的人也就更少了,本來不想更新tkinter??吹胶芏嗳嗽趯Wtkinter,其實用Python做布局,沒有人這么干。但還是更新幾節(jié)tkinter,在Python從入門到大師教程中來。
tkinter
Tkinter包是Python附帶的標準軟件包,所以我們不需要安裝任何東西就可以使用它。
窗口主體框架
每一個 tkinter 應用的主體框架都可以包含下面這部分. 定義 window 窗口 和 window的一些屬性, 然后書寫窗口內容, 最后執(zhí)行window.mainloop讓窗口活起來.
import?tkinter?as?tk
window?=?tk.Tk()
window.title('my?window')
window.geometry('200x100')
#?這里是窗口的內容
window.mainloop()

窗口內容
這次我們會建立一個用來描述的標簽 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!',????#?標簽的文字
????bg='green',?????#?背景顏色
????font=('Arial',?12),?????#?字體和字體大小
????width=15,?height=2??#?標簽長寬
????)
l.pack()????#?固定窗口位置
window.mainloop()

控件
上面的Label就是一個控件,還有很多的,如按鈕,標簽和文本框等,如下圖所示

控件自帶的共同屬性,如大小,字體和顏色等。可根據(jù)控件展現(xiàn)形式選擇相應的屬性,具體屬性如下表:

tkinter綁定事件
tkinter綁定事件,就是定義一個函數(shù),然后通過command屬性傳入函數(shù)名,下面通過Button綁定事件,點擊就出現(xiàn)Runsen愛學習
from?tkinter?import?*
def?p_label():
????global?root
????Lb?=?Label(root,?text='Runsen愛學習')
????Lb.pack()
root?=?Tk()
root.title("應用程序窗口")
B_n?=?Button(root,?text='點我',?command=p_label,?bg='red')??#?command后面不能有任何的標點符號
B_n.pack()
root.mainloop()

布局顯示
一個窗口都應該有布局,就是pack的時候需要設置side,expand需要擴展嗎,fill需要填充嗎
from?tkinter?import?*
root?=?Tk()
root.title("應用程序窗口")
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還有一個grid,grid將組件布局為表格
下面做一個電話撥號盤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,?#?設置邊框格式
??????????????????????padx=10,?#?加寬標簽
??????????????????????text=labels[r][c])?#?標簽文本
????????label.grid(row=r,?column=c)?#?將標簽放置在r行c列
root.mainloop()

制作一個日歷
上面教你做一個電話撥號盤GUI,下面能做一個簡單的日歷嗎?
我看你就不會,不是我瞧不起你

放心,有我在。這需要導入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()

豐富我們的日歷
上面的日歷就是一個辣雞,啥功能都沒有,需求很簡單,就是來兩個按鈕實現(xiàn)向上翻,向下翻。
向上翻,向下翻兩個按鈕就需要清空界面,再把日歷加到labels列表中 ?,放置日歷。好像很簡單,其實就是這么簡單。
大家想一想,怎么做出來。我還是給標準實現(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列表:放置“星期”的標題
????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)?#?網(wǎng)格布局
#?默認日期
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()
運行一波,來一個最終實現(xiàn)gif效果圖。

?本文已收錄 GitHub,傳送門~[1] ,里面更有大廠面試完整考點,歡迎 Star。
?
Reference
傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100
更多的文章
點擊下面小程序
- END -

