1. PHP-GTK介紹 1.1 PHP-GTK PHP-GTK是PHP的延伸模組,它可以讓程式設計師寫出在客戶端執行的、且獨立的GUI的程式。這個模組不允許在浏覽器上顯視GTK+的程式,它一開始就是開發來寫獨立的GUI程式的。 1.2 GTK GTK原本是為GIMP,一個GUI的影像處理軟體而開發的。GTK+是GIMP的套裝工具。GTK+從這裡開始發展,直到現在已經成為Gnome的中心(Gnome是一個桌面環境)。後來GTK+也已經被推廣到BeOS和Win32,使得它成為PHP延伸模組的最佳選擇,維持PHP可以跨平台並可以用PHP為Linux,BeOS,Windows等平台開發視窗介面的程式。 2. PHP-GTK概念 2.1 前言 接下來就要教各位一點點比較觀念性的東西羅┅因為這章的概念都是非常重要的,所以就算不懂,也還是要慢慢的看懂它,不然┅以後就┅。還有,接下來的內容不建議沒有程式設計經驗的讀者閱讀,因為有很多的觀念很容易會搞不清楚。還有,接下來該用英文的部分我都會用英文,這樣大家在看國外文件的時候才不會不知所措,加油吧!!如果對本章有任何不懂之處,請自行查閱 PHP-GTK Manual:http://gtk.php.net/manual/en/ 2.2 Widget(s) Widget是一個GUI程式中基本的functions和forms。最常用的幾個Widget是:label、button、window、frame和text box。所有的widget都是來自於一個抽象的基本class─GtkWidget。每個widget都是一個class 一個Widget一生大概都有五個時期: 1. 建立(Creation):宣告一個物件(declaring an object) 2. 放置(Placement):將它加入一個容器中(adding it to a container) 3. 信號連接(Signal Connection):接收信號以及進行動作(the action it will perform) 4. 顯示(Display):它是否是可見的(whether it is viewable or not) 5. 刪除(Destruction):關閉程式(closing of a program) 2.3 Container(s) Container是一個可以包含其他widget的widget。大部分的widget都是container,例如:GtkWindow、GtkTable和GtkBox。除了這點之外,container跟其他的widget沒兩樣,也可以被放到其他container去。而所有的container都是來自於一個class─GtkContainer,本身來自於GtkWidget的class。所以container也是widget的一種。 2.4 Signal(s) 當程式設計師在程式中做了一個動作時,程式需要有一個動作來回應使用者的動作。Signals使程式可以知道使用者做了動作並可以觸發適合的回應。 例如,當使用者按了一個可以開新視窗的按鈕(GtkButton),程式認出這個請求,於是就開了一個新的視窗。這件事可以經由signal來做到。當按鈕按下去之後,會使widget發出一個signal,接著再由該signal觸發callbacks,產生一個新的視窗(GtkWindow)。 2.5 Callback(s) Callback就是當signal送出之後,被signal喚起的function。Callback會執行function傳回一個值或是做一個動作。Callback就是signal的handler funciton。它可以是該signal的預設handler或著是程式設計師定義的function。要建立一個callback,就必須把function connect 到 signal。 2.6 Signal Inheritance(繼承) 和methods一樣,signals可以被物件繼承。一個widget可以送出任何它的parent widget可以送出的還有它自己特有的signal。 2.7 Connecting Signals 你必須為PHP-GTK指定一個callback function當signal送出時來對signal做回應。把一個signal連接到一個function可以用connect() 這個object 方法達成。 如下: connect("destroy", "shutdown"); //建立一個GtkButton,按鈕文字為"按我" $button = &new GtkButton("按我"); $button->connect("clicked", "you_clicked"); //把GtkButton放到是container的GtkWindow中 $window->add($button); //顯示$window以及它的所有child widget $window->show_all(); //進入程式主回圈(即程式啟動之意) gtk::main(); ?> 執行它的話,就會出現一個視窗,裡面有一個寫著"按我"的按鈕,按下按鈕程式就會執行you_clicked函式。在這個程式中,$window物件的"destroy" signal是在使用者按下視窗右上角的"X"時會送出的;而$button物件的"clicked" signal是在使用者按下該按鈕的時候會送出的。最後那一行的gtk::main() 是一定要執行的,這樣才能告訴電腦要開始執行程式,既然有開始執行,那就一定有停止吧? 沒錯,用gtk::main_quit() 就可以停止程式了。 看完了以上的范例,有些讀者可能會有疑問「如果我想執行送出signal的widget之外的widget的method怎麼辦?」,這時候,就要用另一個method了 a connect_object(),它可以跨物件呼叫方法或是傳遞其他物件做為function的三數。跨物件呼叫方法如下: $window->connect_object("destroy", array("gtk","main_quit")) 如此,在$window物件的"destroy" signal送出的時候就會喚起gtk::main_quit()這個方法,程式就會終指執行。 在介紹連接方法的最後,再提一下connect() 和 connect_object() 的自訂增加要傳給callback function的三數的辦法。見例子: connect("clicked","who_are_you",$parameter); $button2 = &new GtkButton("測試二"); //將"clicked" signal連接到kill_the_button1函式,附加三數$button1 $button2->connect_object("clicked","kill_the_button1",$button1); function who_are_you($widget,$parameter){ echo $parameter; } function kill_the_button($button){ $button->destroy(); } ?> 注意那兩個function,who_are_you有兩個三數對吧? 第一個是做什麼用的呢?為什麼它會自動出現?? 因為,每個signal的callback function都會因為signal的不同而加上一些內定一定會傳入callback function的三數,而基本上所有的signal都至少會傳給callback function一個三數a產生該signal的物件。所以who_are_you的第一個三數就是$button1,而第二個就是$parameter,也就是新超人。那kill_the_button函式就不一樣羅~ 因為connect_object()函式會呼略原本signal的callback function的預設三數,所以kill_the_button就只有附加在connect_object最後的$button1三數了,如此,kill_the_button就可以呼叫$button1的方法或是取得它的屬性,這裡呼叫了$button1的destroy方法,於是$button1就會被消滅。 2.8 Event(s) Event是signal的一種,但是它的用途還有功能都非常強大。就signal來說,signal這種東西都是內建在widget上的,所以,例如GtkWindow沒有"clicked"signal,那麼在不用event signal的情況下,GtkWindow是決對不可能送出clicked之類的signal的。那如果用了event signal呢? Event signal是可以允許被加到任何的widget上的,所以就算這個widget本來沒有發出"clicked"signal的功能,你也可以用add_events() 來為它加上按了它之後event signal會做什麼樣的反應。而event signal中包含的資訊比較多,比如說當你在使用"key-press-event"這個event signal的時候,同時也會記錄到你按下的是什麼按鍵,於是通常event signal的callback function格式內定會有兩個三數,第一個依然是送出signal的widget,而第二個就是$event,這個$event是一個class,裡面的屬性和方法會因為送過來的event signal種類而不同。就"key-press-event"傳回的$event class來說,裡面有一個屬性是keyval,內容就是使用者按的是哪一個鍵。這些對於一個程式設計師來說常常是很有用的資訊。所以event的重要性是不可忽視的,就算剛開始會有點不懂,也要慢慢的融入才行。這一節也非常重要。 3. 安裝PHP-GTK 3.1 在Windows系統下安裝 首先要從http://gtk.php.net/download.php下載...HP-GTK的windows binary檔案(本文撰寫時為0.5.1版)。 接著來看看PHP-GTK 0.5.1 binary檔的內容: php4 → php 和 php-gtk binary 檔案 winnt → 預設的php.ini檔案 winntsystem32 → gtk binaries used by extension test → 幾個測試用的檔案 README.txt → 安裝說明檔 開始安裝: 1. 復制 php4 的內容到你的php安裝目錄下(例C:php)。 2. 復制 winnt 的內容到你的winnt資料夾。在Windows NT或Windows2000上是C:winnt,在Window95、98、xp上是C:windows。如果該資料夾裡已經有 php.ini,那就不用做這個動作。 3. 復制 winntsystem32 的內容到你的winntsystem32資料夾。在Windows NT或Windows2000上是C:winntsystem32,在Window95、98、xp上是C:windowssystem32。 4. 復制 test 的內容到你想要執行你的script的地方(此步驟非必要)。 如何執行PHP-GTK程式: PHP-GTK程式可以在「開始」-「執行」下輸入指令(或是建立捷徑)來啟動,如:C:phpphp -q c:phptestgtk.php ## 表示不送印出 HTTP Header,但一直使用這個視窗,直到關閉程式。 C:phpphp -q -c php.ini c:gtk.php ## 同上,但執行指定的php.ini設定。 C:phpphp C:phptestgtk.php ## 表示會送印出 HTTP Header,但一直使 用這個視窗,直到關閉程序 C:phpphp_win C:phptestgtk.php ## 表示不使用視窗,執行後獨立一個執行程式,他是使用 php -q模式,但是只要output出任何字元,例如錯誤訊息,就會停止執行。 3.2 在UNIX系統下安裝 Debian的使用者可以在 http://www.debian.org 下載PHP-GTK的binary檔。系統需求須已安裝下列package: PHP 4.1.0 或之後的版本,必須是編為CGI binary(command-line) 版本,包含所有的header files和devlement scripts。 PHP-GTK支援GTK+ v1.2而需要安裝1.2.6以上版本的GTK+。GTK+ v2.0還未被支援,必須等到它開發完成並