Python 入門指南

單元 22 - GUI 的基本概念與 MVC 模式

~~學習進度表~~

大部分物件導向程式語言在開發 GUI 的部份會採取 MVC 模式 (Model-View-Controller) , M 是我們的 Encrypt 類別 (class) , V 為介面,而 C 為 M 與 V 之間的控制器

EncryptView

M   V   C
↓      ↓
      Encrypt     EncryptController

依 MVC 模式,三個部分都是獨立開發的類別或檔案,在 Python 中就會放在不同的模組 (module) 中,這是說 M 是資料計算的核心類別,其為 ,Model 的頭字母縮寫, V 是介面類別, V 為 View 的頭字母縮寫, C 為控制 M 與 V 之間交流的類別, C 則是 Controller 的頭字母縮寫。

標準程式庫 (standard library) 中的圖形介面模組 (module)Tk模組名稱為 tkinterTk 在國外已經發展的相當成熟,許多程式語言 (programming language) 也都直接內建 Tk

我們的 M 是 Encrypt 類別,放在 encrypt 模組中, V 預計為 EncryptView 類別,而 C 為 EncryptController 類別,下一單元才會正式介紹 EncryptView ,這裡,我們先來看看製作 Tk 視窗的步驟

  1. 建立 Tk 應用物件。
  2. 建立視窗物件。
  3. 加入視窗元件。
  4. 設定版面佈局。
  5. 設定事件方法。
  6. Tk 應用物件呼叫 mainloop() 方法。

基本上 Tk 視窗是運作在 Tk 應用物件之上,先建立視窗物件,然後在視窗物件加入視窗元件,接著設定版面佈局,也就是版面管理 (layout management) ,這需要設定幾何版面管理員 (geometry manager) , Tk 有以下三種幾何版面管理員

版面管理員名稱說明
包裹版面管理員利用 pack() 方法由程式自動安排每個元件的位置。
定位版面管理員利用 place() 方法自訂每個元件的座標。
格子版面管理員利用 grid() 方法用表格的方式安排每個元件,須指定元件所在的格數。

這邊視窗元件先以 Label 為例, Label 就是文字標籤,以下先示範包裹版面管理員的程式

from tkinter import *

root = Tk()
root.title("包裹版面管理員")
text = Label(root, text="Hello World!",
             width="30", height="5",
             bg="black", fg="white")
text.pack()
root.mainloop()

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:tk_demo.py
# 功能:示範 Python 的 Tk 應用程式
# 作者:張凱慶 */

首先引入 tkinter 模組,這裡用 from 然後 import 加上星號表示引入 tkinter 的所有定義

from tkinter import *

下面進入步驟 1 ,也就是建立 Tk 應用物件

root = Tk()

底下這一行是設定視窗標題

root.title("包裹版面管理員")

步驟 2 建立視窗物件,這裡視窗物件直接是一個 Label

text = Label(root, text="Hello World!",
             width="30", height="5",
             bg="black", fg="white")

Label() 的第一個參數root ,表示這個視窗物件 textTk 應用物件 root 的視窗元件,注意後面每一個參數設定都是參數名稱加上指派運算子,然後是設定值,例如

text="Hello World!",

這叫做關鍵字引數 (keyword argument) ,用關鍵字引數來設定參數值就不需要考慮參數順序。這裡 text 表示文字標籤要顯示的文字,此為 "Hello World!"width 為寬,單位為行數, height 為高,單位為列數, bg 為背景顏色, "black" 為黑色, fg 為前景顏色,也就是文字顏色,這裡 "white" 為白色。

視窗物件通常是先建立 Frame , 然後在 Frame 再加入其他的視窗元件,倒是 Tk 在小程式給了個方便,允許直接用視窗元件。

繼續呼叫 pack() 方法就是使用包裹版面管理員,程式會自動調整 Label 於視窗上的位置

text.pack()

這個程式只做示範用,有關步驟 3 設定事件方法留待單元 24 - 設定 command 再做介紹。

最後,由 Tk 物件呼叫 mainloop() 方法, mainloop() 方法的作用是維持視窗在螢幕上顯示

root.mainloop()

執行同樣使用 python 指令

$ python tk_demo.py
 

按下 Enter 鍵就會出現如下視窗

如要結束執行,請按視窗的關閉按鈕,就會回到命令列並且跳到下一個提示字元。

以下示範定位版面管理員的程式

from tkinter import *

root = Tk()
root.title("定位版面管理員")
root.geometry("276x86")
text = Label(root, text="Hello World!",
             width="30", height="5",
             bg="black", fg="white")
text.place(x=0, y=0)
root.mainloop()

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:tk_demo2.py
# 功能:示範 Python 的 Tk 應用程式
# 作者:張凱慶 */

先注意到 Tk 應用物件先呼叫 geometry() 方法設定視窗尺寸,這裡採用 "276x86" ,這會跟寬度 "30" ,高 "5" 的文字標籤一樣大

root.geometry("276x86")

如果不設定視窗尺寸的話, root 會直接套用預設的正方形視窗尺寸。

設定完 Labeltext 變數後, text 再呼叫 place() 方法,並且設定在視窗中的起始座標 xy 的值

text.place(x=0, y=0)

視窗的座標原點在左上角的地方,因此設定成原點會是從左上角開始放置 Label 的文字標籤,往下為 y 的正值,往右為 x 的正值。執行程式,啟動的視窗如下圖

絕大多數的圖形使用者介面程式庫的座標原點都在左上角。

以下示範格子版面管理員的程式

from tkinter import *

root = Tk()
root.title("格子版面管理員")
text = Label(root, text="Hello World!",
             width="30", height="5",
             bg="black", fg="white")
text.grid(row=0, column=0)
root.mainloop()

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:tk_demo3.py
# 功能:示範 Python 的 Tk 應用程式
# 作者:張凱慶 */

格子版面管理員是利用 grid() 設定視窗元件在視窗中在哪一格,其中 row 為從上數下來的第幾列, column 為從左到右數過去的第幾行

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

這裡按習慣把 row 稱列, column 稱行,也就是橫列直行,不過行跟列其實是種習慣稱法,例如講「這一行程式碼」中的行是指橫行,所以關於「行」跟「列」需要理解的是分別指的是橫或直,倒是沒有一定強迫哪一個要直或哪一個要橫。

執行程式,啟動的視窗如下圖

以上三組程式跑出同樣的視窗,在這樣的小程式很容易做到,然而如果要加入更多視窗元件的話,繼續用包裹版面管理員難以控制,定位版面管理員的設定會很繁複,就是需要仔細計算每個視窗元件的尺寸跟座標,反而格子版面管理員的設定相對簡單,因此在下一單元開始寫 EncryptView 類別,我們將用格子版面管理員來進行版面編排。

中英文術語對照
MVC 模式Model-View-Controller
類別class
幾何版面管理員geometry manager
關鍵字引數keyword argument
版面管理layout management
模組module
程式語言programming language
標準程式庫standard library
重點整理
1. MVC 為軟體工程把模型、介面及控制分開的發展模式, M 就是就是處理資料的類別, V 為使用者介面的類別, C 則是控制 M 與 V 交流的類別。
2. 標準模組庫直接整合 Tk ,首先認識有三種版面管理,分別是定位版面管理員、包裹版面管理員、格子版面管理員,其次要認識有哪些視窗元件。
3. 包裹版面管理員適合視窗元件少的小程式使用。
4. 定位版面管理員須自行定義每個視窗元件在視窗中的座標。
5. 格子版面管理員將視窗分成格子,然後將視窗元件放入指定的格子中。
問題與討論
1. 什麼是 MVC 模式?為什麼開發軟體要採用 MVC 模式?
2. 試著比較 Tk 的三種幾何版面管理員的差別,找出常用軟體如記事本、瀏覽器等等,適合套用哪一種管理員?
練習
1. 仿造 tk_demo.py ,寫一個新程式 hello_demo.py ,裡頭設置兩個 Label 、一個 Button 及一個 Entry ,預計改成接收使用者輸入的暱稱,然後跟使用者說「哈囉」。
2. 仿造 tk_demo2.py ,寫一個新程式 hello_demo2.py ,裡頭設置兩個 Label 、一個 Button 及一個 Entry ,預計改成接收使用者輸入的暱稱,然後跟使用者說「哈囉」。
3. 仿造 tk_demo3.py ,寫一個新程式 hello_demo3.py ,裡頭設置兩個 Label 、一個 Button 及一個 Entry ,預計改成接收使用者輸入的暱稱,然後跟使用者說「哈囉」。
4. 承接上一個單元的猜數字遊戲,將新程式寫在 game_demo.py 中,替猜數字遊戲設計圖形介面,裡頭至少需要一個建立新遊戲的 New 按鈕及猜測用的 Guess 按鈕,另外需要一個顯示結果的 Label

上一頁 GUI 篇
回 Python 入門指南首頁
下一頁 單元 23 - Tk 的視窗元件與 V 的部分
回 Python 教材首頁
回程式語言教材首頁