
Tk 的 GUI 事件 (event) 由替每個視窗元件設定 command , command 就是指定與該元件連動的方法 (method)

我們的 EncryptGUI 中有 New 、 Load 、 Save 、 Encode 、 Decode 、 Clear 與 Copy 等七個按鈕,每個按鈕都要設計一個專屬方法。
這裡,先不急著實作七個按鈕的方法,因為每個方法都還牽涉到一些其他概念,我們改成先寫一個發展中的版本,讓每個按鈕都有功能,卻是相對簡化許多的功能。
簡單說,就是先讓按鈕做簡單的事情就好,那要什麼樣的事情呢?由於 self.dt 是提示訊息欄,本來按下按鈕就要顯示訊息到提示訊息欄,那我們就先讓按下按鈕顯示這是什麼按鈕就好了, encrypt_gui.py 的程式碼修改如下
| 001 | from tkinter import * |
| 002 | from tkinter.ttk import * |
| 003 | |
| 004 | # Encrypt 的 GUI 類別 |
| 005 | class EncryptGUI(Frame): |
| 006 | # 設定初值 |
| 007 | def __init__(self, master=None): |
| 008 | Frame.__init__(self, master) |
| 009 | self.grid() |
| 010 | self.createWidgets() |
| 011 | |
| 012 | # 建立所有視窗元件 |
| 013 | def createWidgets(self): |
| 014 | self.it = Label(self) |
| 015 | self.it["text"] = "Input:" |
| 016 | self.it.grid(row=0, column=0) |
| 017 | self.ifd = Entry(self) |
| 018 | self.ifd["width"] = 60 |
| 019 | self.ifd.grid(row=0, column=1, |
| 020 | columnspan=6) |
| 021 | |
| 022 | self.ot = Label(self) |
| 023 | self.ot["text"] = "Output:" |
| 024 | self.ot.grid(row=1, column=0) |
| 025 | self.ofd = Entry(self) |
| 026 | self.ofd["width"] = 60 |
| 027 | self.ofd.grid(row=1, column=1, |
| 028 | columnspan=6) |
| 029 | |
| 030 | self.nb = Button(self) |
| 031 | self.nb["text"] = "New" |
| 032 | self.nb.grid(row=2, column=0) |
| 033 | self.nb["command"] = self.nm |
| 034 | self.lb = Button(self) |
| 035 | self.lb["text"] = "Load" |
| 036 | self.lb.grid(row=2, column=1) |
| 037 | self.lb["command"] = self.lm |
| 038 | self.sb = Button(self) |
| 039 | self.sb["text"] = "Save" |
| 040 | self.sb.grid(row=2, column=2) |
| 041 | self.sb["command"] = self.sm |
| 042 | self.eb = Button(self) |
| 043 | self.eb["text"] = "Encode" |
| 044 | self.eb.grid(row=2, column=3) |
| 045 | self.eb["command"] = self.em |
| 046 | self.db = Button(self) |
| 047 | self.db["text"] = "Decode" |
| 048 | self.db.grid(row=2, column=4) |
| 049 | self.db["command"] = self.dm |
| 050 | self.cb = Button(self) |
| 051 | self.cb["text"] = "Clear" |
| 052 | self.cb.grid(row=2, column=5) |
| 053 | self.cb["command"] = self.cm |
| 054 | self.cb2 = Button(self) |
| 055 | self.cb2["text"] = "Copy" |
| 056 | self.cb2.grid(row=2, column=6) |
| 057 | self.cb2["command"] = self.cm2 |
| 058 | |
| 059 | self.dt = Label(self) |
| 060 | m = "something happened" |
| 061 | self.dt["text"] = m |
| 062 | self.dt.grid(row=3, column=0, |
| 063 | columnspan=7) |
| 064 | |
| 065 | # 按下 New 按鈕的事件 |
| 066 | def nm(self): |
| 067 | self.dt["text"] = "New Button" |
| 068 | |
| 069 | # 按下 Load 按鈕的事件 |
| 070 | def lm(self): |
| 071 | self.dt["text"] = "Load Button" |
| 072 | |
| 073 | # 按下 Save 按鈕的事件 |
| 074 | def sm(self): |
| 075 | self.dt["text"] = "Save Button" |
| 076 | |
| 077 | # 按下 Encode 按鈕的事件 |
| 078 | def em(self): |
| 079 | self.dt["text"] = "Encode Button" |
| 080 | |
| 081 | # 按下 Decode 按鈕的事件 |
| 082 | def dm(self): |
| 083 | self.dt["text"] = "Decode Button" |
| 084 | |
| 085 | # 按下 Clear 按鈕的事件 |
| 086 | def cm(self): |
| 087 | self.dt["text"] = "Clear Button" |
| 088 | |
| 089 | # 按下 Copy 按鈕的事件 |
| 090 | def cm2(self): |
| 091 | self.dt["text"] = "Copy Button" |
| 092 | |
| 093 | # GUI 執行部分 |
| 094 | if __name__ == '__main__': |
| 095 | root = Tk() |
| 096 | app = EncryptGUI(master=root) |
| 097 | app.mainloop() |
| 098 | |
| 099 | # 檔名: encrypt_gui.py |
| 100 | # 作者: Kaiching Chang |
| 101 | # 時間: July, 2014 |
每個按鈕都新增設定 command
| 033 | self.nb["command"] = self.nm |
command 就是對應的方法名稱,至於方法內容就是簡單的印出按了哪個按鈕
| 065 | # 按下 New 按鈕的事件 |
| 066 | def nm(self): |
| 067 | self.dt["text"] = "New Button" |
來執行看看囉!以下是點擊 Encode 按鈕的結果

結果 ok !接下來,我們要開始整合 Encrypt 類別 (class) 囉!
中英文術語對照
| 事件 | event |
| 方法 | method |
| 類別 | class |
重點整理
- Tk 的視窗元件由設定 command ,來指定與元件連動的方法。
- 我們先寫一個發展中的版本,設定按下按鈕後在訊息欄顯示按鈕名稱。
問題與討論
- 為什麼每個按鈕都要有專屬方法?可以幾個按鈕共用一個方法,或是某個按鈕不跟方法連結嗎?
- 除了顯示按鈕名稱,還有什麼簡單事情是可以先給按鈕做的?
練習
- 承接上一個單元的 tk_demo2.py ,設定為按下按鈕後在 Label 顯示訊息。
- 承接上一個單元的 guessgame_gui.py ,設定為按下按鈕後在 Label 顯示按下哪個按鈕。
the end
沒有留言:
張貼留言