嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

為應用程式設計圖形化介面,使用Python Tkinter 模組

作者 張嘉鈞
難度 普通
材料表 Windows 或Linux 環境電腦

目錄

  1. Tkinter 簡介
  2. 第一個 Tkinter程式 : Hello World
  3. 視窗元件總攬
  4. 簡單的元件實作

3-1. 標籤 ( Label )

3-2. 按鈕 ( Button )

3-3. 使用Label顯示圖片

  1. 我的設計方法與Grid 佈局
  2. 進階GUI實作

6-1. 全螢幕視窗

6-2. 按按鈕開啟圖像

6-3. 開啟攝影機進行即時影像擷取

Tkinter 簡介

因為近年來Python的使用率大幅提升,根據TIOBE的資料顯示2020年全球的程式語言使用率Python穩居第三,而PyPl的套件安裝Python的數量則是第一名。為什麼提到這件事呢? Tkinter是TK GUI整合到Python中的GUI開發套件,更白話一點就是Python內建的GUI設計套件,當你使用Python開發專案的時候可以考慮使用Tkinter來製作操作介面。在Python開發GUI的榜上前兩位是Tkinter與PyQt,兩者的差別:pyqt整合度高、有圖形化介面可以使用;Tkinter因為是Python自帶的GUI套件,功能簡單但效能可能更好。如果要追求高顏質的介面,我比較推薦pyqt,但如果是只簡單的介面設計,追求效率就選擇Tkinter吧!

1、第一個 Tkinter程式 : Hello World

我們來建構一個簡單的視窗並且顯示Hello World吧!

步驟一、導入 Tkinter 函式庫 ( Python 3 ),如果使用Python 2 則T要大寫

import tkinter as tk

步驟二、定義一個視窗 名叫 window

window = tk.Tk()

步驟三、設定標題

window.title('window')

步驟四、設定像素大小

window.geometry('600x800')

步驟五、宣告一個標籤

lbl_1 = tk.Label(window, text='Hello World', bg='yellow', fg='#263238', font=('Arial', 12))

步驟六、設定放置的位置 ( 使用 grid 佈局 )

lbl_1.grid(column=0, row=0)

步驟七、主視窗迴圈顯示

window.mainloop()

完整程式碼如下:

import tkinter as tk

window = tk.Tk()
window.title('window')
window.geometry('500x100')
lbl_1 = tk.Label(window, text='Hello World', bg='yellow', fg='#263238', font=('Arial', 12))
lbl_1.grid(column=0, row=0)
window.mainloop()

這樣就完成一個簡單的GUI介面囉!結果如下:

01_hello_world_a4ccb36e8a00fd7c03660ea3fcf24d88018d3cbf.jpg

 

2、視窗元件總攬

這邊順便提供一個很實用的教學文件:https://tkdocs.com/tutorial/index.html

類別 介紹
Frame 視窗。
Label 文字標籤。
Button 按鈕。
Canvas 可以用來繪圖、文字等都可以,像我就會來拿放圖片。
Checkbutton 核取按鈕。
Entry 文字輸入欄。
Listbox 列表選單。
Menu 選單列的下拉式選單。
LabelFrame 文字標籤視窗。
MenuButton 選單的選項。
Message 類似 Label ,可多行。
OptionMenu 下拉式的選項選單。
PaneWindow 類似 Frame ,可包含其他視窗元件。
Radiobutton 單選按鈕。
Scale 拉桿。
Scrollbar 捲軸。
Spinbox 微調器
Text 文字方塊。
Toplevel 新增視窗。

3、簡單的元件實作

由於元件的參數或詳細用法網路上已經有很多介紹了,所以我這邊快速帶過。

3-1. 標籤 ( Label )

02_label_5c9c9696bef0306126f1f72330c4dd84c8b58c7f.jpg

我們在宣告標籤的時候,需要先宣告一個標籤,再給予位置,如果沒有給予位置資訊的話將不會被放在視窗上面,這邊我們使用grid來告訴視窗標籤要放在該容器中的 (0, 0) 這個位置,此外沒有給定視窗寬、高大小的話,視窗會依照Widget大小而自動去調整:

import tkinter as tk

window = tk.Tk()
window.title('window')

def create_label(txt):
    lbl_1 = tk.Label(window, text=txt, bg='yellow', fg='#263238', font=('Arial', 12), width=100, height=2)
    lbl_1.grid(column=0, row=0)

create_label('Hello World !!!')

window.mainloop()

稍微介紹一下元件的參數,大部分的元件在宣告的時候,可以引入的參數都雷同,第一個是你要放在哪個容器當中,我們給予window,代表這個標籤會放在window當中,而text代表文字,bg是background背景,fg是foreground前景,可以當作是文字的顏色,font是文字的格式width、height是寬與高,這邊要注意的是他們的單位是字元寬度、字元高度,而不是像素值,此外還有很多屬性可以用像是邊框、影像、對齊樣式等等。

3-2. 按鈕 ( Button )

03_button_9e6099abf704c6f7d1ea70653cf7d2081288f683.jpg

上方宣告 label的時候是將 width 跟 height 帶入到宣告的時候,也有另外一個做法,就是使用字典的方式宣告屬性,bt_1 的 ‘width’ 屬性要定義成如何,這邊可以注意到 width 是定義字元的寬、height是定義字元的高,我個人覺得tkinter的元件大小很難控制,與解析度大小沒有一定的關係,待會在教怎麼樣可以平均大小跟自動縮放;此外這邊還有提供 activebackground跟activeforeground為按下按鈕的背景、前景顏色變化。

import tkinter as tk

window = tk.Tk()
window.title('window')

def create_button(txt):
    bt_1 = tk.Button(window, text=txt, bg='red', fg='white', font=('Arial', 12))
    bt_1['width'] = 50
    bt_1['height'] = 4
    bt_1['activebackground'] = 'red'        # 按鈕被按下的背景顏色
    bt_1['activeforeground'] = 'yellow'     # 按鈕被按下的文字顏色 ( 前景 )

    bt_1.grid(column=0, row=0)

create_button('Button')

window.mainloop()

3-3. 使用Label顯示圖片

04_cat_714af4c35ae5e63433db4e309e9f65e9f32e7032.jpg

這邊要注意的是需要將圖片轉成Tkinter 可以讀的格式:

import tkinter as tk
from PIL import Image, ImageTk

window = tk.Tk()
window.title('window')
# 放照片在UI上
def create_label_image():
    img = Image.open('./images/cat_1.jpg')                    # 讀取圖片
    img = img.resize( (img.width // 10, img.height // 10) )   # 縮小圖片
    imgTk =  ImageTk.PhotoImage(img)                        # 轉換成Tkinter可以用的圖片
    lbl_2 = tk.Label(window, image=imgTk)                   # 宣告標籤並且設定圖片
    lbl_2.image = imgTk
    lbl_2.grid(column=0, row=0)                             # 排版位置

create_label_image()
window.mainloop()

4、我的設計方法與Grid 佈局

在開始實作複雜的GUI前,我先介紹一下我設計GUI時的做法以及使用Grid編排的方式。首先,在設計一個GUI之前我會先進行空間的區隔。

f1_frame_746509720ffde81955961195d0a611e8d3c79ee1.png

我會透過frame按照上方的圖繪分成四個顏色的區塊,灰色是主要視窗,藍色為顯示圖片的區塊,橘色為顯示文字的區塊,綠色為按鈕的區塊。

實作程式碼如下:

import tkinter as tk
from PIL import Image, ImageTk

window = tk.Tk()
window.title('Window')

div_size = 200
img_size = div_size * 2
div1 = tk.Frame(window,  width=img_size , height=img_size , bg='blue')
div2 = tk.Frame(window,  width=div_size , height=div_size , bg='orange')
div3 = tk.Frame(window,  width=div_size , height=div_size , bg='green')

div1.grid(column=0, row=0, rowspan=2)
div2.grid(column=1, row=0)
div3.grid(column=1, row=1)

顯示結果如下:

06_frames_ea35174b05941dbc6e726e92463362357dae470e.jpg

但目前會有縮放的問題,當你放大之後他的大小仍然會保持原樣,不會跟著縮放:

07_windows_bbb17e157e67f6bef54dc8c8682cbf36f11bf7bb.jpg

倘若要能夠伸縮需要使用到 columnconfigure、rowconfigure,其中可以用的參數:

minsize

最小的視窗大小( pixel )

pad

上下左右各添加多少 ( pixel )

weight

如果weight=0的話就不會進行縮放的動作,可以想像是權重值 ( 1 除以 weight ),參考下列範例當有兩個元件需要定義網格的時候:

div1.columnconfigure(0, weight=1)

div1.columnconfigure(1, weight=5)

這時候Tkinter會將六分之一的空間分配給第0欄的元件,其餘六分之五給第二欄的元件。

08_weights_1_2d216b436cc9574677bd48945410d90c97118f30.jpg

如果大小都是填1則是各一半

div1.columnconfigure(0, weight=1)

div1.columnconfigure(1, weight=1)

09_weights_2_e3f9a6633562cfb13587d39ea1290f9ca99bebb1.jpg

接下來針對先前寫好的frame添加權重,這邊我先寫了一個副函式 ( define_layout ) 用來定義grid,引入obj為UI widget、cols該widget中有幾欄、row該widget中有幾列:

def define_layout(obj, cols=1, rows=1):
    
    def method(trg, col, row):
        
        for c in range(cols):    
            trg.columnconfigure(c, weight=1)
        for r in range(rows):
            trg.rowconfigure(r, weight=1)

    if type(obj)==list:        
        [ method(trg, cols, rows) for trg in obj ]
    else:
        trg = obj
        method(trg, cols, rows)

接著套用到剛剛的框架,稍微修改了一些地方,主要在grid的部分加上了 pad以及 sticky,pad是向外拓展 ( pixel );sticky 是對齊方式,這邊用 align_mode 來統一所有的對其方式,而給予字串 ‘nswe’ 是置中的意思 ( n 上 s 下 w左 e 右):

window = tk.Tk()
window.title('Window')
align_mode = 'nswe'
pad = 5

div_size = 200
img_size = div_size * 2
div1 = tk.Frame(window,  width=img_size , height=img_size , bg='blue')
div2 = tk.Frame(window,  width=div_size , height=div_size , bg='orange')
div3 = tk.Frame(window,  width=div_size , height=div_size , bg='green')

div1.grid(column=0, row=0, padx=pad, pady=pad, rowspan=2, sticky=align_mode)
div2.grid(column=1, row=0, padx=pad, pady=pad, sticky=align_mode)
div3.grid(column=1, row=1, padx=pad, pady=pad, sticky=align_mode)

定義好UI之後在來處理佈局問題,先來看第一行要注意的地方是如果下層UI要套用權重上層的也一定要套用,所以如果三個frame要套用的話,最主要的視窗window也需要使用weight分配:

define_layout(window, cols=2, rows=2)
define_layout([div1, div2, div3])

執行下去可以看到進行縮放的時候,我們的三個frame也會跟著拉伸:

10_frames_2_3e2c844ff9df4964c902cf746f172dab428784c8.jpg

11_frames_3_e01ff6ec95b6a99e9f87115b20c6b0dbed6b95c5.jpg

接著再把需要的UI項目放進去,完整程式碼如下:

window = tk.Tk()
window.title('Window')
align_mode = 'nswe'
pad = 5

div_size = 200
img_size = div_size * 2
div1 = tk.Frame(window,  width=img_size , height=img_size , bg='blue')
div2 = tk.Frame(window,  width=div_size , height=div_size , bg='orange')
div3 = tk.Frame(window,  width=div_size , height=div_size , bg='green')

window.update()
win_size = min( window.winfo_width(), window.winfo_height())
print(win_size)

div1.grid(column=0, row=0, padx=pad, pady=pad, rowspan=2, sticky=align_mode)
div2.grid(column=1, row=0, padx=pad, pady=pad, sticky=align_mode)
div3.grid(column=1, row=1, padx=pad, pady=pad, sticky=align_mode)

define_layout(window, cols=2, rows=2)
define_layout([div1, div2, div3])

im = Image.open('./images/cat_1.jpg')
imTK = ImageTk.PhotoImage( im.resize( (img_size, img_size) ) )

image_main = tk.Label(div1, image=imTK)
image_main['height'] = img_size
image_main['width'] = img_size

image_main.grid(column=0, row=0, sticky=align_mode)

lbl_title1 = tk.Label(div2, text='Hello', bg='orange', fg='white')
lbl_title2 = tk.Label(div2, text="World", bg='orange', fg='white')

lbl_title1.grid(column=0, row=0, sticky=align_mode)
lbl_title2.grid(column=0, row=1, sticky=align_mode)

bt1 = tk.Button(div3, text='Button 1', bg='green', fg='white')
bt2 = tk.Button(div3, text='Button 2', bg='green', fg='white')
bt3 = tk.Button(div3, text='Button 3', bg='green', fg='white')
bt4 = tk.Button(div3, text='Button 4', bg='green', fg='white')

bt1.grid(column=0, row=0, sticky=align_mode)
bt2.grid(column=0, row=1, sticky=align_mode)
bt3.grid(column=0, row=2, sticky=align_mode)
bt4.grid(column=0, row=3, sticky=align_mode)

bt1['command'] = lambda : get_size(window, image_main, im)

define_layout(window, cols=2, rows=2)
define_layout(div1)
define_layout(div2, rows=2)
define_layout(div3, rows=4)

window.mainloop()

最終結果:

>12_cat_2_6c2e9219cb0b78a638da5bee1cd25015fea506e0.jpg

13_cat_3_4eae9ebd595a14dd531b7d08dc2d5142f9efd857.jpg</p

那布局的使用方法,大家在這裡應該也練習得差不多了,接下來會提供幾個常用的功能,像是全螢幕、按按鈕互動、即時影響讀取等等。

6、進階GUI實作

在這裡為了參數調用的方便,我會使用Class來完成接下來的實作。

6-1. 全螢幕視窗 ( bind )

我們預設按下F12的時候切換成全螢幕視窗,在按下一次則返回,這邊會使用到 bind 的函式,這個是可以將函式綁定到動作上面,像是按下左鍵、放開左鍵、按下F12等。首先我們要先能夠將視窗全螢幕,在Windows環境下我們將去調整他的attributes成為 ‘-fullscreen,而Linux環境下則調整成 ‘-zoomed’,範例程式如下:

window.attributes('-fullscreen', True)  # For Windows
window.attributes('-zoomed', True)      # For Linux

接著我們要想辦法辨識系統環境,在Python中自帶一個函式庫叫 Platform,可以使用Platform.system()得知現在的環境,在我的程式當中如果系統是Windows的話就回傳1不是的話就回傳 0 ,進而再給予特定的全螢幕變數。

def toggle_fullScreen(self, event):

    is_windows = lambda : 1 if platform.system() == 'Windows' else 0

    self.isFullScreen = not self.isFullScreen
    self.window.attributes("-fullscreen" if is_windows() else "-zoomed", self.isFullScreen)

接著使用bind將動作連結到toggle_fullScreen函式:

# 切換全螢幕
self.isFullScreen = False
self.window.bind('<F12>', self.toggle_fullScreen)

接著就可以執行看看了,在給完整程式碼之前可以先看一下結果:

14_cat_4_183127f2e3f2edb995906f157defb5811f3dfede.jpg

cat_on_white_background_3b080d12c263031ab1963252943c313ab001dac2.jpg

由於全螢幕的關係工具列也會被取消掉,不過我常做的GUI都會帶一個關閉程式的按鈕,或者我們也可以透過 bind 將 ESC 按鍵綁定關閉視窗:

def del_window(self, event):
    self.window.destroy()

self.window.bind('<Escape>', self.del_window)

完整程式碼如下:

self.window = tk.Tk()
self.window.title('Window')

im = Image.open('./images/cat.jpg').resize( (300, 300) )
imTK = ImageTk.PhotoImage( im )
self.lbl_img = tk.Label(self.window, image=imTK)
self.lbl_img.image = imTK
self.lbl_img.grid(column=0, row=0, sticky='nwes')
# 切換全螢幕
self.isFullScreen = False
self.window.bind('<F12>', self.toggle_fullScreen)

self.window.mainloop()

6-2. 按按鈕開啟圖像 ( command )

_e7cc16d915dba711f40eb4db573d79753f8d249a.gif

整體設計概念很簡單,在一開始的時候由frame將按鈕及圖片顯示區塊隔開,宣告個別元件。

def define_layout(self, obj, cols=1, rows=1):
    
  def method(trg, col, row):
        [ trg.columnconfigure(c, weight=1)  for c in range(cols) ]  
        [ trg.rowconfigure(r, weight=1)     for r in range(rows) ]
    if type(obj)==list:        
        [ method(trg, cols, rows) for trg in obj ]
    else:
        method(obj, cols, rows)

self.window = tk.Tk()
self.window.title('Window')

self.align_mode = 'nsew'
self.pad = 10

self.div_size, self.img_size = 200, 400
self.div1 = tk.Frame(self.window,  width=self.div_size , height=self.div_size)
self.div2 = tk.Frame(self.window,  width=self.img_size , height=self.img_size) 

self.div1.grid(column=0, row=0, padx=self.pad, pady=self.pad, sticky=self.align_mode)
self.div2.grid(column=0, row=1, padx=self.pad, pady=self.pad, sticky=self.align_mode)

self.bt1 = tk.Button(self.div1, text='Cat')
self.bt1.grid(column=0, row=0, sticky=self.align_mode)
self.bt2 = tk.Button(self.div1, text='Dog')
self.bt2.grid(column=1, row=0, sticky=self.align_mode)
self.bt3 = tk.Button(self.div1, text='Clear')
self.bt3.grid(column=2, row=0, sticky=self.align_mode)
self.bt4 = tk.Button(self.div1, text='Quit')
self.bt4.grid(column=3, row=0, sticky=self.align_mode)

self.define_layout(self.window, cols=1, rows=2)

接著先來顯示圖片,由於一開始開啟程式希望是沒有圖片的所以給予空白值,但因為是空白值寬高也是0,圖片區域的frame會因此變得很小,所以我將該frame的參數grid_propagate() 設為False,這個動作目的是要不要讓該frame被子元件的圖片大小給影響,也就是維持一開始預設的大小:

self.imTK = ''      # 預設給空白
self.lbl_img = tk.Label(self.div2, image=self.imTK)
self.lbl_img.image = self.imTK
self.lbl_img.grid(column=0, row=0, sticky=self.align_mode)
self.div2.grid_propagate(0)                 # 不會被子元件改變大小

接著就是按鈕事件的宣告,按下按鈕的時候希望執行什麼動作:

def bt1_event(self):
    im = Image.open('./images/cat_1.jpg')
    self.imTK = ImageTk.PhotoImage( im.resize( (self.img_size, self.img_size) ) )
    self.lbl_img.configure(image=self.imTK) # image有時會被清除
    self.lbl_img.image = self.imTK    # 防止圖片被垃圾清掃給除掉

def bt2_event(self):
    im = Image.open('./images/dog_1.jpg')
    self.imTK = ImageTk.PhotoImage( im.resize( (self.img_size, self.img_size) ) )
    self.lbl_img.configure(image=self.imTK)  # image有時會被清除
    self.lbl_img.image = self.imTK    # 防止圖片被垃圾清掃給除掉

def bt3_event(self):
    self.lbl_img.configure(image='')

# 綁定按鈕事件
self.bt1['command'] = self.bt1_event
self.bt2['command'] = self.bt2_event
self.bt3['command'] = self.bt3_event
# self.bt4['command'] = lambda : self.window.destroy()
self.bt4.bind('<Button-1>', self.del_window)

可以注意到綁定方法與剛剛全螢幕視窗的做法不太相同,可以在宣告按鈕的時候直接用command綁定事件,也可以透過我這種方式額外宣告,在bt4_event可以看到用bind的方法也是可以的,只是要去找一下對應的動作參數是什麼,像在這裡如果bt4被左鍵點擊定義為 <’Button-1’>,除此之外我也提供了lambda的寫法,可以再參考看看。

6-3. 隨視窗大小改變圖片大小(靜態) – bind 延伸

從上一個案例開始應用到bind之後,我們可以在視窗大小改變的時候 ( Configure ) 或許該視窗的大小或某一個元件的大小,實驗程式如下,大家可以玩玩看,注意這個是靜態的,只有在點擊按鈕生成圖片的時候才會符合縮放後的大小:

def bt1_event(self):
    im = Image.open('./images/cat_1.jpg')
    self.imTK = ImageTk.PhotoImage( im.resize( (self.w, self.h) ) )
    self.lbl_img.configure(image=self.imTK)
    self.lbl_img.image = self.imTK         

def get_size(self, event, obj=''):

    trg_obj = self.window if obj == '' else obj
    self.w, self.h = trg_obj.winfo_width(), trg_obj.winfo_height()
    print(f'\r{(self.w, self.h)}', end='')

# 每次改變狀態,都會獲取 某元件 大小
self.window.bind('<Configure>', lambda event, obj=self.div2 :self.get_size(event, obj))
# 按鈕的部分
self.bt1['command'] = self.bt1_event

1743_3fa64e81d246329dfe718403f83fba89670cb96f.jpg

6-4. 開啟攝影機進行即時影像擷取 (after)

即時影像的部分會帶到一個新的使用方法以及一個新的UI元件,第一個元件,由於是即時影像,如果有寫過OpenCV即時影像擷取的人應該知道,需要寫一個While迴圈不斷擷取幀 ( Frame ),並且透過不斷顯示獲取到的幀來構成一個即時影像畫面,而在Tkinter中也是要如此,但這邊我們會使用 「after」來模擬While迴圈;另個要介紹的Widget是對話框,我個人平常不會寫但是有時候蠻好玩的,所以也記錄下來使用方法。

先來完成簡單版本的即時影像擷取,先宣告一個架構出來:

window = tk.Tk()
window.title('Video Stream')

main = tk.Frame(window, bg="white")
main.grid()
video = tk.Label(main)
video.grid()
window.bind('<Escape>', lambda event: window.destroy())

接下來透OpenCV取得攝影機以及進行即時影像擷取,使用after來模擬While不停執行的狀況,這邊10是指10「毫秒」:

# 宣告攝影機
status, frame = 0, []
cap = cv2.VideoCapture(0)   

def stream():

    # 讀取當前的影像
    global status, frame
    status, frame = cap.read()
    # 如果有影像的話
    if status:
        # 將 OpenCV 色改格式 ( BGR ) 轉換成 RGB
        im_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
        # 將 OpenCV 圖檔轉換成 PIL
        im_pil = Image.fromarray(im_rgb)
        # 轉換成 ImageTK
        imgTK = ImageTk.PhotoImage(image=im_pil)
        # 放入圖片
        video.configure(image=imgTK)
        # 防止圖片丟失,做二次確認
        video.image = imgTK
    # 10 豪秒 後執行 stream 函式,這裡是模擬 While 迴圈的部分
    window.after(10, stream) 

# 先執行一次
stream()

window.mainloop()

# 釋出攝影機記憶體、關閉所有視窗
cap.release()
cv2.destroyAllWindows()

對話框的部分,加在主程式裡就可以了:

def quit(self, event):

    quit_check = tk.messagebox.askokcancel('提示', '是否要退出?')
    if quit_check:
        print('離開程式')
        cv2.destroyAllWindows()
        self.cap.release()
        self.window.destroy()	

self.window.bind('<Escape>', self.quit)

1841_645cd08cf2f6f8a49ea552f5ab3a561e8a255073.jpg

6-5. 圖片隨著視窗大小而改變 (動態)

有了模擬迴圈的功能,我們可以來玩玩看圖片的動態縮放了!由於如果一直即時改變會相當的消耗資源,所以我這邊有設定參數resize_rate,可以決定幾秒更新一次,使用的架構是之前寫的範例,先來看看結果吧!

1940_28fcc9d26d37b8e91f78fedfda00aba837282509.jpg

首先是每次視窗更動的時候擷取大小:

def get_size(self, event):
    self.w = self.div2.winfo_width()
    self.h = self.div2.winfo_height()

self.window.bind('<ButtonRelease>', lambda event: self.get_size)

接著是Update的部分,這裡的邏輯是「當我沒有縮放視窗的時候不斷獲取當前時間,一旦更動視窗大小N秒後進行縮放,進行縮放的時候會抓取最後的視窗大小」

def update(self):
    if self.w == self.div2.winfo_width() and self.h ==self.div2.winfo_height():
        self.reszie_time = time.time()
    
    if self.w != self.div2.winfo_width() or self.h !=self.div2.winfo_height():
        if time.time()-self.reszie_time>= self.resize_rate and self.im is not '':
            self.w, self.h = self.div2.winfo_width(), self.div2.winfo_height()    
            self.imTK = ImageTk.PhotoImage( self.im.resize( (self.w, self.h) ) )
            self.lbl_img.configure(image=self.imTK)
            self.lbl_img.image = self.imTK             
            
    self.window.after(10, self.update)

self.reszie_time, self.resize_rate = 0, 0.5
self.w, self.h = self.div2.winfo_width(), self.div2.winfo_height()
self.update()
self.window.mainloop()

2022_a3a282a120d5c47d3a13ba9ccc58c17f51e086bc.jpg

結語

經過一連串小範例的實作,是否了解Tkinter的用法了?當然如果要熟悉的話還是多找幾個小專題是做看看,一定會越來越厲害的。一些邊緣裝置專題分享,或多或少都會結合小的螢幕去做觸碰操作或顯示,這時候製作GUI就很重要了!接下來的文章會模擬工廠產線問題進行小專題製作,屆時也會製作一個小介面供使用者使用,更多小技巧會收錄哦!

相關文章

Python is TIOBE's Programming Language of 2020!

Tkinter's Grid Geometry Manager

[Tkinter 教程15] event 事件绑定

如何在 Tkinter 中建立全屏視窗

Tkinter 消息提示

CAVEDU Education is devoted into robotics education and maker movement since 2008, and is intensively active in teaching fundamental knowledge and skills. We had published many books for readers in all ages, topics including Deep Learning, edge computing, App Inventor, IoT and robotics. Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw
DesignSpark Electrical Logolinkedin