2017年9月4日 星期一

程式設計師需要知道的圖形使用者介面(GUI)觀念 ( Basic GUI Concepts for a Programmer )

早期的電腦(DOS時代)都是文字介面,也就沒什麼講究畫面的設計方式,約莫五六年前吧,UI設計已經成為一個產品重要的因素之一,最經典的例子就是iPhone手機的硬體介面。想了解什麼是UI可參考此文:什麼是 UI/使用者介面。本文會以程式設計師的角度來談談所需要知道的觀念:

  • 什麼是圖形使用者介面(Graphical User Interface)。
  • 事件處理(Event Handling)。
  • MVC模式(Model–view–controller)。
  • 手機GUI程式和電腦GUI程式有什麼不同。


什麼是圖形使用者介面(Graphical User Interface)

簡單來說就是使用者與電腦互動的圖形畫面,例如Linux上的Unity、GNOME、KDE、Android手機畫面、iPhone手機畫面等。請參考由 https://en.wikipedia.org/wiki/Graphical_user_interface所節錄的畫面:

事件處理(Event Handling)

看過GUI的畫面之後,程式設計師應該會想知道如何寫一個GUI程式吧!那就需要了解GUI程式中是如何處理使用者按下滑鼠左鍵、用鍵盤打字等訊息。這部分的觀念清楚後,要學GUI程式設計就不會那麼難了。首先可以玩玩Code.org上的製作一個Flappy遊戲來認識什麼是事件。

再來看一下鍵盤與滑鼠事件在電腦中的運作情況,見下圖:

電腦上所有的硬體都先由驅動程式做處理,當使用者按下滑鼠左鍵時,驅動程式會通知作業系統「滑鼠左鍵按下」,接著作業系統會將此訊息送給有註冊「滑鼠左鍵按下」事件且運用中的程式,接著就會根據程式中的功能做處理,以「按下鍵盤」事件為例子,整個流程大約如下:

  1. 使用者「按下鍵盤」。
  2. 驅動程式通知作業統使用者「按下鍵盤」。
  3. 作業系統的Event API發送訊息「按下鍵盤」給有註冊訊息處理的程式(Programs)。
  4. 執行 FunctionA、FunctionB、FunctionC 程式功能。

以上是精簡過的流程,不同的作業系統與不同的GUI Libraries會有些差異。有了以上的觀念後,就可以在程式中來做GUI的事件處理了。以Java語言為例(詳細解說可參考此文),在程式內的流程如下圖:


以按鈕處理滑鼠按下的事件為例,上圖的Event Source就是Button,Event Listener為Mouse Listener,而Event Handler可能有五種:press、release、click、enter、exit。程式碼大概如下:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MouseClickDemo implements MouseListener {
        // Other components initialization
        // Register for mouse events on Button.
        btn.addMouseListener(this);
        addMouseListener(this);
    ...

    public void mousePressed(MouseEvent e) {
 // don't care, do nothing
    }

    public void mouseReleased(MouseEvent e) {
 // don't care, do nothing
    }

    public void mouseEntered(MouseEvent e) {
 // don't care, do nothing

    }

    public void mouseExited(MouseEvent e) {
 // don't care, do nothing
    }

    public void mouseClicked(MouseEvent e) {
 // Put your code here to handle mouse click event
    }

}

若是用 Python 和 Tkinter 呢?底下為一個參考的做法:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# !/usr/bin/python3
import tkinter
from tkinter import messagebox

mainWin = tkinter.Tk()

# Event Handler for mouse click
def btnHandler():
   messagebox.showinfo( "Btn Click", "Button click")

# Register mouse click event
Btn = tkinter.Button(mainWin, text ="Click Me", command = btnHandler)

Btn.pack()
mainWin.mainloop()
其他語言就請參考所用的 GUI 程式庫了。(題外話:Windows上的組合語言可參考小木偶的網頁)

MVC模式(Model–view–controller)

MVC 是一種設計UI的軟體架構模式,原本是在桌面環境下的設計架構,目前在網頁(web)、行動設備(Mobile)等軟體開發上越來越流行了,甚至有些軟體開發的framework都依照MVC的架構來設計函式庫,所以開始來聊聊MVC的觀念,底下會以Web Application來說明MVC,請見下圖:
Model:由Controller來管理,用來儲存與表示資料結構。若是以資料庫系統來儲存的話,Model就是用來執行新增(Create)、查詢(Query)、修改(Modify)之資料庫系統。

View:呈現在使用者面前的資訊,可以為網頁或是網頁上的圖片、文字等,資料處理後的網頁結果就是View。

Controller:用來處理使用者與Model之間的操作,Web Server可為Web Application 中的 Controller。

手機GUI程式和電腦GUI程式有什麼不同

目前手機作業系統以Android與iOS為主流,所以會針對這兩個系統做說明,而目前Android所採用的程式語言為Java,所以在GUI的事件處理方式與桌機上的Java GUI是一樣的方式,而Android系統的GUI就不是以AWT或是SWING為函式庫,而是在Java API Framework下的View System,整體架構跟Desktop不一樣。而 iOS 呢?用的是Cocoa API,多了個 Event Loop 的觀念,而大多數的GUI函式庫是以 Event Loop 為事件處理的實作方式。Cocoa API 也是用事件處理的方式來判斷「鍵盤按下、滑鼠左鍵按下」等事件。總結一句話,「用的GUI函式庫不一樣,呈現畫面的API就不一樣,但事件處理到處存在。」

以上用圖片與簡短文字說明,希望讀者對GUI程式設計有個基礎觀念。