大部分物件導向程式語言在開發 GUI 的部份會採取 MVC 模式 (Model-View-Controller) , M 是我們的 Encrypt 類別 (class) , V 為介面,而 C 為 M 與 V 之間的控制器
↑
M V C
↓ ↓
Encrypt EncryptController
依 MVC 模式,三個部分都是獨立開發的類別或檔案,在 Python 中就會放在不同的模組 (module) 中,這是說 M 是資料計算的核心類別,其為 ,Model 的頭字母縮寫, V 是介面類別, V 為 View 的頭字母縮寫, C 為控制 M 與 V 之間交流的類別, C 則是 Controller 的頭字母縮寫。
標準程式庫 (standard library) 中的圖形介面模組 (module) 為 Tk ,模組名稱為 tkinter , Tk 在國外已經發展的相當成熟,許多程式語言 (programming language) 也都直接內建 Tk 。
我們的 M 是 Encrypt 類別,放在 encrypt 模組中, V 預計為 EncryptView 類別,而 C 為 EncryptController 類別,下一單元才會正式介紹 EncryptView ,這裡,我們先來看看製作 Tk 視窗的步驟
- 建立 Tk 應用物件。
- 建立視窗物件。
- 加入視窗元件。
- 設定版面佈局。
- 設定事件方法。
- 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()
#《程式語言教學誌》的範例程式
# http://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 ,表示這個視窗物件 text 為 Tk 應用物件 root 的視窗元件,注意後面每一個參數設定都是參數名稱加上指派運算子,然後是設定值,例如
text="Hello World!",
這叫做關鍵字引數 (keyword argument) ,用關鍵字引數來設定參數值就不需要考慮參數順序。這裡 text 表示文字標籤要顯示的文字,此為 "Hello World!" , width 為寬,單位為行數, height 為高,單位為列數, bg 為背景顏色, "black" 為黑色, fg 為前景顏色,也就是文字顏色,這裡 "white" 為白色。
繼續呼叫 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()
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:tk_demo2.py
# 功能:示範 Python 的 Tk 應用程式
# 作者:張凱慶 */
先注意到 Tk 應用物件先呼叫 geometry() 方法設定視窗尺寸,這裡採用 "276x86" ,這會跟寬度 "30" ,高 "5" 的文字標籤一樣大
root.geometry("276x86")
如果不設定視窗尺寸的話, root 會直接套用預設的正方形視窗尺寸。
設定完 Label 的 text 變數後, text 再呼叫 place() 方法,並且設定在視窗中的起始座標 x 及 y 的值
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()
#《程式語言教學誌》的範例程式
# http://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 。 |
相關教學影片
- 第八堂課導覽 ⇨ YouTube 頁面連結
- 什麼是 MVC 模式? ⇨ YouTube 頁面連結
- 製作 Tk 應用程式的基本步驟 ⇨ YouTube 頁面連結
- Tk 的三種版面管理員 ⇨ YouTube 頁面連結