簡介
簡介
- Tcl
- 動态解釋型程式設計語言
- 可獨立執行,多嵌入C程式中作為腳本引擎,或者作為使用Tk工具包的接口
- Tcl庫可以建立一個或多個Tcl解釋器執行個體,然後在這些執行個體上運作C或Tcl指令和腳本
- 每個解釋器有一個事件隊列,接受事件并處理他們
- Tk
- 用C語言實作的一個Tcl包
- 添加了自定義指令建立和操作GUI元件
- 是唯一一個專門為進階動态語言(如 Python、 Tcl、 Ruby、 Perl 等)設計的跨平台(Windows、 Mac、 Unix)圖形使用者界面工具包
- Tk的元件可以支援豐富的自定義,但風格比較過時
- 使用Tcl的事件隊列生成和處理GUI事件
- Ttk
- 主體化Tk(Themed Tk)
- 相比經典Tk,提供更新的Tk元件,提供更好的樣式
- Tkinter是Python 的标準 Tk GUI 工具包的接口,可以實作簡單的跨平台GUI程式
- Tkinter 是 Python 内置的标準 GUI 庫,無需額外安裝
- Python2.x 版本使用的庫名為 Tkinter
- Python3.x 版本使用的庫名為 tkinter
參考
Python GUI程式設計(Tkinter) 菜鳥教程
TkDocs
TkDocs Tutorial
TkDocs reference
Python interface to Tcl/Tk
Tk Commands
Button
Python2.x vs Python3.x
Python2.x | Python3.x |
---|---|
Tkinter | tkinter |
ScrolledText | tkinter.scrolledtext |
ttk | tkinter.ttk |
tkMesageBox | tkinter.messagebox |
tkAxxBxx | tkinter.axxbxx |
- 導入tkinter,處理下python2和python3的差異
- 繼承Frame Class,初始化Frame,初始化其他參數
- 擷取螢幕大小,設定App大小為螢幕大小的百分之80
- 設定App标題
- 以自身為master建立控件,配置控件,監聽處理控件事件
- 放置控件,pack()或grid()或place()
- 程式進入主循環,顯示程式mainloop()

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
import tkFont as tk_font
import tkMessageBox as tk_messagebox
else:
import tkinter as tk ## Python 3.x
import tkinter.font as tk_font
import tkinter.messagebox as tk_messagebox
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.font = tk_font.Font(family='Helvetica', size=36, weight='bold')
self.config(bg='black')
self.setScreenSize()
# self = tk.Frame()
# self.master = tk.Tk()
self.master.title("ButtonTest")
self.createWidgets()
def setScreenSize(self):
ratio = 0.8
screen_h = self.master.winfo_screenheight()
screen_w = self.master.winfo_screenwidth()
# print(screen_h, screen_w)
app_h = round(screen_h * ratio)
app_w = round(screen_w * ratio)
y = round(screen_h * (1 - ratio) / 2.0)
x = round(screen_w * (1 - ratio) / 2.0)
geometry = '' + str(app_w) + 'x' + str(app_h) + '+' + str(x) + '+' + str(y)
# print(geometry)
self.master.geometry(geometry)
def createWidgets(self):
self.button = tk.Button(self, text="hello", bg="red", fg="#0000FF", font=self.font, command=self.helloCallBack)
self.draw()
def helloCallBack(self):
tk_messagebox.showinfo("Title", "Message")
def draw(self):
self.pack(padx=50, pady=50)
self.button.pack(padx=50, pady=50)
self.mainloop()
if __name__ == '__main__':
App()
Layout
我們嘗試實作一個如下的布局來學習tkinter的布局
pack
pack CMD
anchor + side定位
- anchor
- 元件放在父元件的什麼位置,上下左右搭配8個方向,然後還有中間
- s要搭配side=bottom,不然跟n效果一樣
- side
- 放在上一個元件的上下左右,比如left,就是放在上一個元件左邊
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import random
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
import tkMessageBox as tk_messagebox
else:
import tkinter as tk ## Python 3.x
import tkinter.messagebox as tk_messagebox
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master.title("pack")
self.font = 'Times 20 bold'
self.config(height=600, width=600)
self.createWidgets()
def createWidgets(self):
self.createFrame1()
self.createFrame2()
self.createFrame3()
self.draw()
def createFrame1(self):
frame = tk.Frame(self, height=200, width=800)
self.createBtn(frame, anchor='NW')
self.createBtn(frame, anchor='N')
self.createBtn(frame, anchor='NE')
frame.pack()
frame.pack_propagate(0)
def createFrame2(self):
frame = tk.Frame(self, height=200, width=800)
self.createBtn(frame, anchor='W', side='left')
self.createBtn(frame, anchor='CENTER', side=None)
self.createBtn(frame, anchor='E', side='right')
frame.pack()
frame.pack_propagate(0)
def createFrame3(self):
frame = tk.Frame(self, height=200, width=800)
self.createBtn(frame, anchor='SW', side='bottom')
self.createBtn(frame, anchor='S', side='bottom')
self.createBtn(frame, anchor='SE', side='bottom')
frame.pack(side='bottom')
frame.pack_propagate(0)
def createBtn(self, parent, anchor, side='top'):
bg = self.getRandColor()
frame = tk.Frame(parent, height=200, width=200, bg=bg)
button = tk.Button(frame, text=anchor)
frame.pack(side='left')
frame.pack_propagate(0)
if(anchor == 'CENTER'):
button.pack(padx=50, pady=50, expand=True)
else:
button.pack(anchor=anchor.lower(), side=side)
def getRandColor(self):
return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()
def getRandRGB(self):
return '{:02X}'.format(random.randint(0, 255))
def helloCallBack(self):
tk_messagebox.showinfo("Title", "Message")
def draw(self):
self.pack()
self.pack_propagate(0)
self.mainloop()
if __name__ == '__main__':
App()
假設我隻想用一個Frame,就會顯得很奇怪
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import random
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
import tkMessageBox as tk_messagebox
else:
import tkinter as tk ## Python 3.x
import tkinter.messagebox as tk_messagebox
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master.title("pack")
self.font = 'Times 20 bold'
self.config(height=600, width=600)
self.createWidgets()
def createWidgets(self):
self.createBtn(self, anchor='W', side='left')
self.createBtn(self, anchor='NW', side='top')
self.createBtn(self, anchor='N', side='top')
self.createBtn(self, anchor='NE', side='top')
self.createBtn(self, anchor='CENTER', side='bottom')
self.createBtn(self, anchor='SW', side='bottom')
self.createBtn(self, anchor='S', side='bottom')
self.createBtn(self, anchor='SE', side='bottom')
self.createBtn(self, anchor='E', side='right')
self.draw()
def createBtn(self, parent, anchor, side='top'):
bg = self.getRandColor()
button = tk.Button(parent, text=anchor, bg=self.getRandColor())
if(anchor == 'CENTER'):
button.pack(padx=50, pady=50, expand=True)
else:
button.pack(anchor=anchor.lower(), side=side)
def getRandColor(self):
return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()
def getRandRGB(self):
return '{:02X}'.format(random.randint(0, 255))
def helloCallBack(self):
tk_messagebox.showinfo("Title", "Message")
def draw(self):
self.pack()
self.pack_propagate(0)
self.mainloop()
if __name__ == '__main__':
App()
place
- x,y
- 絕對定位
- relx,rely
- 相對定義,relx=0就是最左,relx=1就是最右
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import random
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
import tkMessageBox as tk_messagebox
else:
import tkinter as tk ## Python 3.x
import tkinter.messagebox as tk_messagebox
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master.title("pack")
self.font = 'Times 20 bold'
self.config(height=600, width=600)
self.createWidgets()
def createWidgets(self):
self.createBtn(0, 0, 'nw')
self.createBtn(0.5, 0, 'n')
self.createBtn(1, 0, 'ne')
self.createBtn(0, 0.5, 'w')
self.createBtn(0.5, 0.5, 'center')
self.createBtn(1, 0.5, 'e')
self.createBtn(0, 1, 'sw')
self.createBtn(0.5, 1, 's')
self.createBtn(1, 1, 'se')
self.draw()
def createBtn(self, x, y, anchor):
button = tk.Button(self, text='(' + str(x) + ', ' + str(y) + ')', bg=self.getRandColor())
button.place(relx=x, rely=y, anchor=anchor)
def getRandColor(self):
return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()
def getRandRGB(self):
return '{:02X}'.format(random.randint(0, 255))
def draw(self):
self.pack()
self.pack_propagate(0)
self.mainloop()
if __name__ == '__main__':
App()
grid
這個就是css中的table,比較簡單了
- row,rowspan
- column,columnspan
- sticky
- 元件大小小于父元件時怎麼填充父元件
- nesw:水準垂直都拉伸填充
- ns:垂直填充
- ew:水準填充
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import random
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
import tkMessageBox as tk_messagebox
else:
import tkinter as tk ## Python 3.x
import tkinter.messagebox as tk_messagebox
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master.title("pack")
self.font = 'Times 20 bold'
# self.config(height=600, width=600)
self.createWidgets()
def createWidgets(self):
self.createBtn(0, 0, 1, 2)
self.createBtn(0, 2, 2, 1)
self.createBtn(1, 0, 2, 1)
self.createBtn(1, 1)
self.createBtn(2, 1, 1, 2)
self.draw()
def createBtn(self, row, col, rowspan = 1, colspan = 1):
button = tk.Button(self, text='(' + str(row) + ', ' + str(col) + ')', bg=self.getRandColor(), width=20, height=8)
button.grid(row=row, column=col, rowspan=rowspan, columnspan=colspan, sticky="nesw")
def getRandColor(self):
return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()
def getRandRGB(self):
return '{:02X}'.format(random.randint(0, 255))
def draw(self):
self.pack()
self.pack_propagate(0)
self.mainloop()
if __name__ == '__main__':
App()