Python可以這樣玩(7):GUI 程式設計
這一課算是一個里程碑,代表我們學會了 Python 程式語言的基礎邏輯部分,準備進入到介面的設計。
在此之前,我們所寫的程式都是命令列的程式,透過 input()、print() 一行一行跟程式互動,這是一種古老的方式,現在已經進入 Windows 時代了,如果還用以前DOS的方式寫程式,有很多事情會無法達成,例如,你要寫一個計算機程式,請問如何用DOS模式來寫呢?
Hello World! For Windows
按照慣例,我們又要寫一個 Hello World 程式,創建我們第一個 Windows 視窗:
開啟一個新的檔案,輸入下面的程式碼:
from
tkinter import *
my_window
= Tk()
my_window.title('Hello
World!')
my_window.geometry('400x100')
my_window.mainloop()
這程式分成三個部分,首先一定要 import tkinter 的所有方法,第二步透過 Tk() 函數創建一個視窗物件 my_window,然後定義其中的 title 與 geometry (寬 x 高)。第三步就是進入視窗程式的主迴圈。
空白視窗的執行結果如下(那根羽毛其實很像台灣):
接下來,我們要將 tkinter 物件加入我們的空白視窗,tkinter 提供非常多的視窗物件,例如: Button、Label、Canvas、Menu、Entry 等等等,我們就從最基本的開始。
Label 標籤
Label 是用來顯示單列文字的物件,請接著修改前面的程式碼:
from
tkinter import *
my_window
= Tk()
my_window.title('Hello
World!')
my_window.geometry('400x100')
my_label
= Label(my_window, text = 'Hello Windows!', bg = 'yellow')
my_label.pack()
my_window.mainloop()
要在視窗上面建置物件有兩個步驟,首先透過 Label() 創建物件並傳入必要的參數,然後使用 pack() 布局方式將此物件放置在視窗裡。pack() 是最基本的布局方式,就是由上到下依序放置。結果如下:
Entry 文字方塊
前面的 Label 可以用來輸出文字,但是如何讓使用者輸入文字呢?就必須使用 Entry,修改程式如下:
from
tkinter import *
my_window
= Tk()
my_window.title('Hello
World!')
my_window.geometry('400x100')
my_label
= Label(my_window, text = 'Hello Windows!', bg = 'yellow')
my_label.pack()
my_enter
= Entry(my_window, width = 20)
my_enter.pack()
my_window.mainloop()
結果如下:
到目前為止,我們已經可以顯示字串,以及輸入字串,但是什麼事情都不能做,因為我們還沒有處理輸入完畢之後要執行的命令。這個命令通常會在
Button 裡面處理。所以接下來,我們來介紹最重要的部分,Button。
事件驅動程式設計
設計視窗應用程式,屬於事件驅動程式設計。還記得在前面的主程式裡面,有一個
mainloop(),這個函數就是讓我們的視窗進入一個等待事件的迴圈,當我們在視窗上面的某個物件上,例如按鈕,用滑鼠點了一下的時候,這個迴圈就會偵測到一個 mouse click 的事件,然後再按照我們替這個事件事先設計好的 command 來執行。
Button 按鈕
按鈕是最常用來接受事件的物件,我們現在將前面的視窗程式,設計成讓使用者在 Entry
裡面輸入文字,按下按鈕之後,就在 Label 中顯示所輸入的文字。程式碼如下:
裡面所有修改的部分,我都做了備註,方便閱讀,執行的結果如下:
加法器:
隨堂測驗
建立一個加法計算機
輸出結果如上:
from ___________ import
*
my_window = ______
my_window._______('小計算機')
my_window.__________('400x200')
# 加入一個字串變數,用來控制 Label 的 textvariable
label_var =
_____________
label_var.set('0')
# 原本的 text 改成 textvariable
my_label = Label(___________,
______________ = label_var,
width =
20, bg = 'yellow')
my_label.__________
my_label1 = Label(__________,
_____ = '請輸入第一個數字')
my_label1.pack()
my_enter1 = Entry(__________,
width = 20)
my_enter1.pack()
my_label2 = Label(__________,
_____ = '請輸入第二個數字')
my_label2.pack()
my_enter2 = Entry(__________,
width = 20)
my_enter2.pack()
# 新增一個 Button 的 command 的處理函數
def click_add():
label_var.set(int(my_enter1.get()) +
int(my_enter2.get()))
# 加入 Button 物件
my_button = Button(________,
_____ = '相加', ________
= _________)
my_button.pack()
# 進入事件迴圈
my_window.mainloop()
messagebox 訊息框
所謂事件驅動程式設計,就是指程式執行之後,會在 mainloop() 迴圈裡面等待事件發生,但是當訊息框這種視窗出現的時候,程式就會跳到訊息框的事件迴圈裡面,除非你做指定的動作,否則不會跳回主迴圈。
訊息框通常用於顯示必須讓使用者注意的文字,除非使用者看到,否則程式就會停在訊息框裡面,我們把第一個 window.py 修改一下,多加一個按鈕,使用者按下按鈕之後出現訊息框,程式執行畫面如下圖:
按下訊息框按鈕:
程式碼如下,我們換了一種 import 寫法,讓程式更具可讀性:
import
tkinter
import
tkinter.messagebox
my_window
= tkinter.Tk()
my_window.title('Hello
World!')
my_window.geometry('400x100')
# 加入一個字串變數,用來控制 Label 的 textvariable
label_var
= tkinter.StringVar()
label_var.set('Hello
Windows!')
# 原本的 text 改成 textvariable
my_label
= tkinter.Label(my_window, textvariable = label_var, bg = 'yellow')
my_label.pack()
my_enter
= tkinter.Entry(my_window, width = 20)
my_enter.pack()
def
click_me():
label_var.set(my_enter.get())
my_button1
= tkinter.Button(my_window, text = 'Click Me!', command = click_me)
my_button1.pack()
def
show_message():
tkinter.messagebox.showinfo(title = '訊息框', message = '請按下OK按鈕')
# 多加一個 Button 物件
my_button2
= tkinter.Button(my_window, text = '訊息框', command = show_message)
my_button2.pack()
# 進入事件迴圈
my_window.mainloop()
要使用messagebox,一定要 import
tkinter 以及 import tkinter.messagebox,兩者缺一不可,我們可以用下面的方式簡化程式:
import tkinter as
tk
import tkinter.messagebox
as tm
my_window =
tk.Tk()
my_window.title('Hello
World!')
my_window.geometry('400x100')
# 加入一個字串變數,用來控制 Label 的 textvariable
label_var =
tk.StringVar()
label_var.set('Hello
Windows!')
# 原本的 text 改成 textvariable
my_label
= tk.Label(my_window, textvariable = label_var, bg = 'yellow')
my_label.pack()
my_enter
= tk.Entry(my_window, width = 20)
my_enter.pack()
def
click_me():
label_var.set(my_enter.get())
my_button1
= tk.Button(my_window, text = 'Click Me!', command = click_me)
my_button1.pack()
def
show_message():
tm.showinfo(title = '訊息框', message = '請按下OK按鈕')
# 多加一個 Button 物件
my_button2
= tk.Button(my_window, text = '訊息框', command = show_message)
my_button2.pack()
# 進入事件迴圈
my_window.mainloop()
很實用~ 非常感謝 ^0^
回覆刪除