原文更豐富
英文不好的朋友也沒有關(guān)系碳抄,下面會給出一些學(xué)習(xí)的例子:
首先我們來看一下常用的TKinter提供的核心小構(gòu)件類:
小構(gòu)件類 | 描述 |
---|---|
Button | 按鈕 |
Canvas | 結(jié)構(gòu)化圖形隅茎,用于繪制圖形,創(chuàng)建圖形編輯器以及實現(xiàn)自定義小構(gòu)件類 |
Checkbutton | 單擊復(fù)選按鈕在值之間切換 |
Entry | 文本域或稱文本框 |
Frame | 容器(可包含其他的小構(gòu)件) |
Label | 顯示文本或圖像 |
Menu | 顯示下拉菜單和彈出菜單的菜單欄 |
Menubutton | 下拉菜單的菜單按鈕 |
Message | 類似于標(biāo)簽顯示文本掉伏,但能自動將文本放在給定寬高內(nèi) |
Radiobutton | 單選按鈕 |
Text | 格式化的文本顯示,支持內(nèi)嵌圖片和文本筹麸,允許用不同風(fēng)格和屬性顯示和編輯文本 |
實例一
- 我們來編寫一個這樣的例子鹦马,使用到了文本輸入、復(fù)選按鈕过椎、單選按鈕室梅、輸入框√读鳎可以學(xué)到如何綁定事件到小構(gòu)件上竞惋。
具體實現(xiàn)代碼如下:
from tkinter import *
class WidgetsDemo:
def __init__(self):
window = Tk()
window.title("組建demo")
#添加一個多選按鈕和單選按鈕到frame1
frame1 = Frame(window)
frame1.pack() #看下面的解釋(包管理器)
self.v1 = IntVar()
cbtBold = Checkbutton(frame1, text = "粗體", variable = self.v1, command = self.processCheckbutton)
self.v2 = IntVar()
rbRed = Radiobutton(frame1, text = "紅色", bg = "red", variable = self.v2, value = 1, command = self.processRaidobutton)
rbYellow = Radiobutton(frame1, text="黃色", bg="yellow", variable=self.v2, value=2, command=self.processRaidobutton)
cbtBold.grid(row = 1, column = 1) #將cbtBold排列在frame1的網(wǎng)格第一行第一列(網(wǎng)格管理器也會在下面有解釋)
rbRed.grid(row=1, column=2)
rbYellow.grid(row=1, column=3)
#添加一個label柜去、entry灰嫉、button和message到frame2
frame2 = Frame(window)frame2.pack()
label = Label(frame2, text = "請輸入名字")
self.name = StringVar()
entryName = Entry(frame2, textvariable = self.name)
btGetName = Button(frame2, text = "獲取名字", command = self.processButton)
message = Message(frame2, text = "組建demo")
label.grid(row = 1, column = 1)
entryName.grid(row = 1, column = 2)
btGetName.grid(row = 1, column = 3)
message.grid(row = 1, column = 4)
#添加一個texttext = Text(window)
text.pack()
text.insert(END, "Tip\n最好的學(xué)習(xí)TKinter方式是讀") #END表示插入到當(dāng)前文本最后
text.insert(END, "這是一些很好的學(xué)習(xí)例子使用他們")
text.insert(END, "創(chuàng)建你自己的應(yīng)用吧")window.mainloop()
def processCheckbutton(self):
print("復(fù)選框按鈕是" + ("被選中" if self.v1.get() == 1 else "未選中"))
def processRaidobutton(self):
print("紅色是" + ("被選中" if self.v2.get() == 1 else "未選中"))
def processButton(self):
print("你的名字是:" + self.name.get())
WidgetsDemo()
代碼中的一些解釋:
包管理器
- frame1.pack():這句話是指使用包管理器將frame1放到容器中。
包管理器可以管理在相同容器中的所有小構(gòu)件的展示方式嗓奢,我們可以使用 fill, expand, side來設(shè)置它們(小構(gòu)件)的展示方式讼撒。官方給出一個例子來解釋這個包管理器的實現(xiàn)原理,可以想象一些有彈性的材料和一個很小的矩形洞股耽,然后按照小構(gòu)件的打包順序依次放進這個洞中根盒,默認是從頂部開始往里放直到全部放置完畢,最后計算出容納所有的小構(gòu)件需要多大的邊界并將它們?nèi)恳频街魅萜髦小?/p>
如果你需要實現(xiàn)更復(fù)雜的布局物蝙,通常不得不使用額外的Frame構(gòu)件炎滞,也能替換使用網(wǎng)格管理器來實現(xiàn)。
Note:不要在同一個窗口中混合使用網(wǎng)格管理器(grid)和包管理器(pack)诬乞。
下面樣式(patterns)舉例:
- 裝滿父容器
#一個小列表占滿父容器
from Tkinter import *
root = Tk()
listbox = Listbox(root)
listbox.pack()
for i in range(20):
listbox.insert(END, str(i))
mainloop()
這個列表默認只會展示10行(超過的部分可滾動顯示)册赛,當(dāng)用戶拖拽放大窗口的時候,Tkinter將會增加包裹列表的內(nèi)邊距震嫉,而不會放大列表本身森瘪,如下圖:
如果我們希望這個列表可以裝滿父容器,并且用戶可以手動拖拽容器來達到放大列表的目的票堵,可以使用fill和expand選項來實現(xiàn)扼睬。
#一個小列表占滿父容器
from Tkinter import *
root = Tk()
listbox = Listbox(root)
listbox.pack(fill=BOTH, expand=1)
for i in range(20):
listbox.insert(END, str(i))
mainloop()
這個fill選項告訴包管理器這個小構(gòu)件(widget)想填充這整個空間,并指定填充方式悴势,BOTH:指定這個構(gòu)件在水平和垂直兩個方向伸展窗宇,X在水平方向伸展措伐,Y在豎直方向伸展。
expand:當(dāng)值非0時担映,是告訴包管理器分配額外的空間給構(gòu)件废士,當(dāng)父容器足夠包裹所有的子構(gòu)件時,多于的擴展空間就會填充在構(gòu)件之間
2, 放置一定數(shù)量的小構(gòu)件
當(dāng)不使用任何參數(shù)的時候蝇完,構(gòu)件就會按照一列排序
from tkinter import *
root = Tk()
w = Label(root, text="Red", bg="red", fg="white")
w.pack()
w = Label(root, text="Green", bg="green", fg="black")
w.pack()
w = Label(root, text="Blue", bg="blue", fg="white")
w.pack()
mainloop()
當(dāng)添加了fill=X后官硝,就可以使構(gòu)件和父容器一樣寬
from tkinter import *
root = Tk()
w = Label(root, text="Red", bg="red", fg="white")
w.pack(fill=X)
w = Label(root, text="Green", bg="green", fg="black")
w.packfill=X()
w = Label(root, text="Blue", bg="blue", fg="white")
w.pack(fill=X)
mainloop()
設(shè)置使構(gòu)件并肩排列,并設(shè)置高度等于父容器
from tkinter import *
root = Tk()
w = Label(root, text="Red", bg="red", fg="white")
w.pack(fill=Y,side=LEFT)
w = Label(root, text="Green", bg="green", fg="black")
w.pack(fill=Y,side=LEFT)
w = Label(root, text="Blue", bg="blue", fg="white")
w.pack(fill=Y,side=LEFT)
mainloop()
關(guān)于包管理器更多點擊查看
網(wǎng)格管理器
-
被譽為Tkinter中最靈活的幾何管理器短蜕,也是最需要學(xué)習(xí)的一種管理器
網(wǎng)格管理器把小部件放在一個二維的表里面氢架,父部件(就是包涵其它部件的主部件)被分成很多行和列,并在行和列所組成的每個單元格里面可以容納一個小部件朋魔。在設(shè)計對話框的時候岖研,只用網(wǎng)格管理器是非常便捷的,當(dāng)然也可以使用包管理器實現(xiàn)警检,但是使用包管理器需要大量額外的frame部件孙援。
-
樣式(patterns)舉例:
使用網(wǎng)格管理器很容易,只需要告訴小部件在網(wǎng)格管理器中的第幾行第幾列扇雕,也不用預(yù)先指定網(wǎng)格管理器的大小拓售,它會根據(jù)內(nèi)部的小部件來設(shè)定自己的大小。
例1:
from tkinter import *
master = Tk()
Label(master, text="First").grid(row=0)
Label(master, text="Second").grid(row=1)
e1 = Entry(master)
e2 = Entry(master)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
mainloop()
當(dāng)沒有給出列數(shù)的時候就默認是0列.
運行上面的代碼得到下面的窗口:
注意每個小部件都呆在他們自己元件的中間镶奉,你可以使用sticky選項來修改這個設(shè)置础淤,它有四個值如下:
值 | 含義 |
---|---|
E | 東(右) |
S | 南(下) |
W | 西(左) |
N | 北(上) |
例如:
from tkinter import *
master = Tk()
Label(master, text="First").grid(row=0, sticky = W)
Label(master, text="Second").grid(row=1, sticky = W)
e1 = Entry(master)
e2 = Entry(master)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
mainloop()
你可以設(shè)置讓一個部件占用多個行或列。columnspan指定列數(shù)哨苛,rowspan指定行數(shù)鸽凶。
from tkinter import *
master = Tk()
Label(master, text="First").grid(row=0, sticky = W)
Label(master, text="Second").grid(row=1, sticky = W)
e1 = Entry(master)
e2 = Entry(master)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
button = Button(master,text = "button")
button.grid(row = 0, column = 2, columnspan = 2, rowspan = 2, padx = 5,
pady = 5, sticky = W + E + N + S)
mainloop()
學(xué)習(xí)更多關(guān)于網(wǎng)格管理器
位置管理器
可以使用位置管理器直接指定小部件在窗口中的x和y值來設(shè)置位置,但是它不能兼容所有的計算機建峭,在不同分辨率的窗口上排列的位置可能會不同玻侥,所以我們盡量避免使用它。更多關(guān)于位置管理器
實例二
可以根據(jù)單選按鈕來切換文字的顏色亿蒸,并根據(jù)輸入改變文字的內(nèi)容:
from tkinter import *
class ChangeLabelDemo:
def __init__(self):
window = Tk()
window.title = "改變labeldemo"
frame1= Frame(window)
frame1.pack()
self.lb1 = Label(frame1, text = "Programming is fun")
self.lb1.pack()
frame2 = Frame(window)
frame2.pack()
label = Label(frame2, text = "輸入")
self.msg = StringVar()
entry = Entry(frame2, textvariable = self.msg)
btChangeText = Button(frame2, text = "改變text", command = self.processButton)
self.v1 = StringVar()
rbRed = Radiobutton(frame2, text = "Red", bg="red",variable=self.v1,value="R",command = self.processRadiobutton)
rbYellow = Radiobutton(frame2, text="Yellow", bg="yellow", variable=self.v1, value="Y", command=self.processRadiobutton)
label.grid(row = 1, column = 1)
entry.grid(row = 1, column = 2)
btChangeText.grid(row = 1, column = 3)
rbRed.grid(row = 1, column = 4)
rbYellow.grid(row = 1, column = 5)
window.mainloop()
def processButton(self):
self.lb1["text"] = self.msg.get()
def processRadiobutton(self):
if self.v1.get() == "R":
self.lb1["fg"] = "red"
elif self.v1.get() == "Y":
self.lb1["fg"] = "yellow"
ChangeLabelDemo()
實例三
畫圖
from tkinter import *
class CanvasDemo:
def __init__(self):
window = Tk()
window.title("CanvasDemo")
self.canvas = Canvas(window, width = 200, height = 100, bg = "White")
self.canvas.pack()
frame = Frame(window)
frame.pack()
btRectangle = Button(frame, text = "長方形", command = self.displayRect)
btOval = Button(frame, text="橢 圓", command=self.displayOval)
btArc = Button(frame, text = "圓 弧", command = self.displayArc)
btPolygon = Button(frame, text="多邊形", command=self.displayPolygon)
btLine = Button(frame, text=" 線 ", command=self.displayLine)
btString = Button(frame, text="文 字", command=self.displayString)
btClear = Button(frame, text="清 空", command=self.clearCanvas)
btRectangle.grid(row = 1, column = 1)
btOval.grid(row=1, column=2)
btArc.grid(row=1, column=3)
btPolygon.grid(row=1, column=4)
btLine.grid(row=1, column=5)
btString.grid(row=1, column=6)
btClear.grid(row=1, column=7)
window.mainloop()
def displayRect(self):
self.canvas.create_rectangle(10, 10, 190, 90, tags = "rect")
def displayOval(self):
self.canvas.create_oval(10, 10, 190, 90, tags = "oval", fill = "red")
def displayArc(self):
self.canvas.create_arc(10, 10, 190, 90, start = 0, extent = 90, width = 8, fill = "red", tags = "arc")
def displayPolygon(self):
self.canvas.create_polygon(10, 10, 190, 90, 30, 50, tags = "polygon")
def displayLine(self):
self.canvas.create_line(10, 10, 190, 90, fill = 'red', tags = "line")
self.canvas.create_line(10, 90, 190, 10, width = 9, arrow = "last", activefill = "blue", tags = "line")
def displayString(self):
self.canvas.create_text(60, 40, text = "Hi,i am a string", font = "Tine 10 bold underline", tags = "string")
def clearCanvas(self):
self.canvas.delete("rect", "oval", "arc", "polygon", "line", "string")
CanvasDemo()
實例四
菜單
可以使用Menu創(chuàng)建菜單凑兰,使用add_command給菜單添加條目
from tkinter import *
class MenuDemo:
def hello(self):
print("hello!")
def __init__(self):
window = Tk()
window.title("Menu demo")
menubar = Menu(window,bg="red")
window.config(menu = menubar)
#創(chuàng)建下拉菜單,并添加到菜單條
operationMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "操作", menu = operationMenu)
operationMenu.add_command(label = "加", command = self.add)
operationMenu.add_command(label="減", command=self.subtract)
operationMenu.add_separator()
operationMenu.add_command(label = "乘", command = self.multiply)
operationMenu.add_command(label="除", command=self.divide)
exitMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "退出", menu = exitMenu)
exitMenu.add_command(label = "退出", command = window.quit)
mainloop()
def add(self):
print("相加")
def subtract(self):
print("相減")
def multiply(self):
print("相乘")
def divide(self):
print("相除")
MenuDemo()
注意:在mac上菜單上在電腦屏幕的最上方的祝懂。
tearoff = 0表示菜單不能移除窗口票摇,add_cascade添加菜單標(biāo)簽,add_command添加條目到菜單砚蓬。
實例五 彈出窗口和綁定鼠標(biāo)事件
from tkinter import *
class MenuDemo:
def __init__(self):
root = Tk()
# create a popup menu
self.menu = Menu(root, tearoff=0)
self.menu.add_command(label="Undo", command=self.hello)
self.menu.add_command(label="Redo", command=self.hello)
# create a canvas
self.frame = Frame(root, width=512, height=512)
self.frame.pack()
# attach popup to canvas
self.frame.bind("<Button-1>", self.popup)
root.mainloop()
def popup(self, event):
self.menu.post(event.x_root, event.y_root)
def hello(self):
print("hello!")
MenuDemo()
當(dāng)點擊鼠標(biāo)左鍵就會出現(xiàn)一個小的菜單欄矢门。可以使用bind方法來綁定事件。
widget.bind(event, handler)
Python中處理的事件和事件屬性如下表:
事件:
事件 | 描述 |
---|---|
<Bi-Motion> | 當(dāng)拖拽小部件的時候 |
<Button-i> | Button-1祟剔、Button-2隔躲、Button-3表示左鍵、中間鍵物延、右鍵點擊 |
<ButtonReleased-i> | 當(dāng)釋放鼠標(biāo)的時候 |
<Double-Button-i> | 當(dāng)雙擊鼠標(biāo)的時候 |
<Enter> | 當(dāng)鼠標(biāo)光圈進入小部件的時候 |
<Key> | 當(dāng)敲擊一個鍵時候 |
<Leave> | 當(dāng)鼠標(biāo)光圈離開小部件的時候 |
<Return> | 當(dāng)敲擊“Enter”鍵時候宣旱,可以將鍵盤任意一個鍵和一個事件綁定 |
<Shift+A> | 當(dāng)敲擊Shif+A的時候,可以和Alt叛薯、Control等組和 |
<Triple-Button-i> | 點擊鼠標(biāo)3次的時候 |
事件屬性:
事件屬性 | 描述 |
---|---|
char | 從鍵盤輸入的字符 |
keycode | 從鍵盤輸入的鍵代碼 |
keysym | 從鍵盤輸入的鍵符號 |
num | 鼠標(biāo)鍵的數(shù)字(1浑吟、2、3) |
widget | 出發(fā)這個事件的小部件的對象 |
x和y | 當(dāng)前鼠標(biāo)在小部件的坐標(biāo)(像素) |
x_root和y_root | 當(dāng)前鼠標(biāo)相對于屏幕左上角的坐標(biāo)(像素) |
其他:
顯示圖像:
可以用如下PhotoImage類創(chuàng)建圖像:
photo = PhotoImage(file = imagefilename)
可以使用標(biāo)簽耗溜、按鈕组力、復(fù)選框、單選框的image屬性添加圖片抖拴,也可以使用Canvas的create_image創(chuàng)建圖片燎字。-
動畫
Canvas類可以用來開發(fā)動畫,使用move(tags阿宅,dx候衍,dy)來實現(xiàn)移動圖片或文字等部件。
canvas.after(times) 暫停
canvas.update()重新顯示畫布 滾動條
可以使用在Text洒放、Canvas蛉鹿、Listbox部件里面。
from tkinter import *
master = Tk()
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(master, yscrollcommand=scrollbar.set)
for i in range(1000):
listbox.insert(END, str(i))
listbox.pack(side=LEFT, fill=BOTH)
scrollbar.config(command=listbox.yview)
mainloop()
上面的方法設(shè)置部件yscrollcommand的滾動回調(diào)set拉馋,并設(shè)置scrollbar部件的方法yview榨为。如果是在水平方向上惨好,可以設(shè)置xscrollcommand,并使用xview方法煌茴。
- 標(biāo)準(zhǔn)對話框
import tkinter.messagebox
import tkinter.simpledialog
import tkinter.colorchooser
tkinter.messagebox.showinfo("showinfo", "this is an info msg")
tkinter.messagebox.showwarning("showinfo", "this is an info msg")
tkinter.messagebox.showerror("showinfo", "this is an info msg")
isYes = tkinter.messagebox.askyesno("askyesno", "continue")
print(isYes)
isOK = tkinter.messagebox.askokcancel("askobcancel","OK?")
print(isOK)
isYesNoCancel = tkinter.messagebox.askyesnocancel("sfs","OK?")
print(isYesNoCancel)
name = tkinter.simpledialog.askstring("ssf", "sdfsdf ")
print(name)
age = tkinter.simpledialog.askinteger("df","sdf")
print(age)