這篇文章是關於 wxPython,但 wxPython 實際是兩件事物的組合體:Python 指令碼語言和 GUI 功能的 wxWindows 庫(關於 wxWindows 的介紹,請參閱 developerWorks上的 “細述 wxWindows” )。wxWindows 庫是為了最大可移植性的 C/C++ 庫,而抽取 GUI 功能。所以 wxWindows 應用程式與生俱來地可以運行在 Windows、帶 X、KDE 或 Gnome 的 UNIX 或者 wxWindows 已移植到的平台上(很不幸,還不包括 Macintosh)。當然 Python, 作為指令碼引擎,具有很強的移植性( 可以 運行在 Macintosh 上,但如果您想要編寫案頭 GUI 代碼,它是不行的)。把 wxWindows 與 Python 指令碼語言群組合起來,意味著:wxPython 應用程式不僅快速和易於編寫,而且可以在不作任何更改情況下,運行在 Windows 或 UNIX 環境下。
您可能想,“但是那也是我有 Java 的原因,Java 也是可移植的。”沒錯,如果您曾試過在 Windows 上安裝 Java 應用程式,您就可能認識到完全不是這麼回事。JAVA 虛擬機器是 大的 ,它並不總是以您所想的方式工作,最糟糕的是,恕我直言,Java 視窗不是真正意義上的視窗,所以 JAVA 虛擬機器與主機系統之間的互動總是有點力不從心。
另一方面,Python 佔有相對小的空間。wxPython 庫的視窗是真正實在的本地視窗,它可以做本地視窗能做的任何事情,使您的 wxPython 程式如同視窗的程式一樣。wxPython 的全部家當可以打包成一個易於安裝的軟體包。也許我是一個固執的人,但我發現做同樣的事情,wxPython 要比 Java 容易得多。
但是您可能沒有聽說過案頭上的 Python,它是伺服器端編程社區的一員,作為指令碼語言這一塊的新生兒(特別是與應用程式伺服器架構串連,如 Zope)。現在人們正趕上 Python 的熱潮。Python 的好處在於,不象其它指令碼語言,它從一開始就是物件導向的語言。所以您不會忽視 Java 由於喜愛 Python 而失去品嘗 OO 好處。
世界上最小的 wxPython 程式,剖析!
聽起來很酷,不是嗎?讓我們看一些代碼,您將會明白我所說的。為了易於討論,我在樣本中插入了一些列標籤。它們不是代碼中的一部分;這就是為什麼它們以 藍色斜體 表示。
清單 1. 一段很小的代碼樣本
[1] import sys, os [2] from wxPython.wx import * [3] class main_window(wxFrame): [4] def __init__(self, parent, id, title): [5] wxFrame.__init__(self, parent, -1, title, size = (200, 100), style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE) [6] self.control = wxTextCtrl(self, -1, style=wxTE_MULTILINE) [7] self.Show(true) [8] class App(wxApp): def OnInit(self): frame = main_window(None, -1, "wxPython: (A Demonstration)") self.SetTopWindow(frame) return true [9] app = App(0) app.MainLoop() |
我們一行行地看,這樣容易明白該代碼的工作原理。這就是為什麼它是世界上最小的 wxPython 程式(我已經把所有無關的細節剔除了)。這段代碼只能建立了一帶有一個編輯欄位的視窗。您可以在這個欄位中編輯,但很明顯沒有辦法儲存。該應用程式看上去就象在 Windows 下一樣(我在裡面輸入了一些東西):
讓我們查看代碼
第一行和第二行是很重要的,在後面會需要它們。事實上,在這個樣本中, 不 需要 sys 和 os ,但由於幾乎每個程式都要用到,所以先把它們放進這段代碼,在後面會針對它們提一些問題。第二行比較有趣,匯入 wxPython 的 wx 庫。當然,wx 庫(基本 wxPython 聲明)包括基本類,如架構和應用程式。
/注意這些行的結尾沒有分號。如果您編寫過 Perl 程式,那您要花費一點功夫來熟悉 Python 的輸入習慣。但等等,它對您來說是陌生的。
在第三行,定義了第一個 Python 類 -- main_window 。 main_window 類是在 wx 模組中定義的 wxFrame 類的衍生類別。正如您猜想的,任何視窗都是 wxFrame 類。
在第四行,定義了初始化方法, main_window 需要定義的唯一方法(當然,其它的在 wxFrame 類中)。初始化方法取參數 parent 、 id 、 title 以及當然還有(作為該對象的引用的) self 。 self 參數是所有 Python 方法的第一個參數。
到 現在為止,如果您編寫過 C/C++,您一定奇怪為什麼沒有花括弧。是很奇怪,Python 把縮排當作重要的句法。任何有子語句的語句以冒號結束,所有該行下的縮排行都屬於以該冒號終止的語句。當縮排回複到原來的縮排時,這一塊就完成了。更為奇 怪的是,這種安排實際上很好用,剛開始編程的程式員發現,這要比用花括弧來說明結構要容易。幸運地是,這還意味著更少的擊鍵次數,所以老程式員也能接受 它。
所以縮排的第 5、6 和 7 行屬於在第 4 行中定義的方法。它們分別調用 wxFrame 父類的初始化常式(實際進行設定一個視窗的所有繁重工作),定義一個控制項以適合新的主視窗,以及確保視窗是可見的。
wxPython 會重新調整父視窗的大小,除非專門告訴不要這樣做。如果您曾編寫過 任何 Microsoft Windows 代碼,通過重新調整控制項大小來匹配父視窗,那您會很快喜歡 wxPython。第 6 行的實際意義是完成一個如同 Notepad 一樣的編輯器。這還不算什麼。用 C/C++ 代碼,則需要 更多 才能實現,不是嗎?記住 -- 我們在這做的不是固定大小的對話方塊,它是真正在視窗主體中和可調整大小的帶編輯器的 Windows- 化應用程式。
讓我們繼續。第 8 行定義了由 wxApp 類派生的 App 對象。它指定了應用程式物件,當運行時,建立一個 main_window 對象,並將它設定為頂部視窗。
最後定義完類,建立應用程式物件,開始運行它的主迴圈。如果您做過任何 C/C++ Windows 編程,會認識到 MainLoop 方法是所有 Windows 程式的正常事件迴圈。這個啟動代碼的風格確實與指令碼語言保持一致。記住,Python 解譯器逐行讀取代碼,並邊讀邊執行它。所以,一旦定義了類,我們只需在指令碼中調用它。
這就是 它 。在這十五行代碼中,實現了一個簡單的文字編輯器,這段代碼無需修改就可以在 Windows 或 UNIX 上運行。而且很容易添加更多特性,這太好了,在下一節將要講述這些。
效能怎樣?
您可能認為,“解釋型語言,效率不高。對於較大的程式,執行起來會很慢。”在一定程度上,這是正確的。事實上,任何影響效能的代碼通常用 C/C++ 重新實現,並連結到 Python 解譯器,這是很容易做的。所以 Python 通常用作綁定功能性模組和 GUI 顯示(或應用程式伺服器功能,如果您需要該功能)的粘合劑。但作為粘合劑,Python 是非常有效。您可以在很短的時間內用 Python 實現真正的程式,由於其物件導向和格式方面有限的創造機會,它們通常可使用好幾個星期。
而且,如果您懷疑使用解釋型語言將大程式結合在一起的想法,那您不妨考慮一下 Microsoft Word 的早期版本是如何?的。至少最近的 Windows 的 Word 版本 6.0,其 Word Basic 函數事實上只是編譯過的代碼;而 GUI 是由 pcode 解釋性型語言構建的。(MS Word 6.0 是用 Word Basic 編寫的,很有效,這是一個很聰明的設計,其原因之一 -- 它是最早用內建解譯器的傳統型程式。)
這裡您所損失的是在效能方面(實際上,很少),但您可以很容易地通過簡化實現和(更重要)簡化定製來彌補。事實上,通過包含 Python 您已經自動包括了易於展現給您的使用者的指令碼語言,同時,對於編程的新手來說,該語言也證明了其易於學習。如果鑽研它,可以用比您現在花費的要少的功夫創作出世界級的軟體。因為,如果該語言能為 Microsoft 服務,那麼,它也能為您服務!
更有趣的事:初步的項目組織器
無論如何,言歸正傳,這裡向您展示一個程式,它事實上做一些值得做的事情。這個程式讓您建立一個稱之為項目的文字檔列表。您可以編輯和儲存它們。更重要的是,您可以很容易地看到如何進一步增強基主要組織器。我使用一個擴充版本為 CVS(標準開放源碼版本控制系統)的前端。 這裡是代碼 。我們(仍然相當小)的應用程式從 15 行擴充到大約 300行,但它現在能實現許多事情。
程式中的趣事
清單 2 中我沒有列出行號,因為很明顯無論如何您都要月閱讀該代碼。我只是一般性地講述一下這個程式是做什麼以及它所用的 Python 與 wxPython 的功能是什麼。有關Python 更詳細說明,請您本地的書店找 Mark Lutz 寫的 O'Reilly 這本書,或者閱讀隨 Python(Guido Rossum 著,Python 的實際作者)一起的文檔。
第一個有趣的事是這個應用程式處理命令列。列表 sys.argv 是命令列,為了使用它您需要理解 Python 列表文法。該樣本用的文法很基本,但這足夠讓您理解這個程式了。
接下來,為了在調試時便於使用,定義一個 MsgBox 函數。注意,用於函式宣告和類方法聲明的文法正好相同。唯一的區別是類方法需要帶參數 self ,該參數包含了正在調用的對象的引用。(當然,您不一定要稱它為 "self"。但如果不這樣做,您會迷惑的。)
真正有趣的是在更為複雜的 __init__ 方法。這裡,我們沒有構建象上例一樣的簡單的、缺乏控制項的菜單,而是構建了一個功能表列,並附加菜單事件到回調常式,以及構建視窗分割欄、樹控制項和編輯控 件。您可以撇去這些來看整個工作怎樣。(如果您以前未做過 GUI 編程,往下看,您會覺得很困難。)Visual Basic 用一種幕後的方式可以做所有這些,但如果在文字編輯器僅僅開啟表格檔案,您仍然可以看到它。如果您曾用 C/C++ 做過 GUI 工作,那會覺得很熟悉。
一旦有構造了的視窗,接下來我們就可以來看程式的實際代碼。首先,在方法 __init__ 後有兩個用於載入和儲存專案檔的方法。在那可以看到 Python 如何用 open 等等來處理檔案 I/O。注意,事實上, 關閉 檔案是一種輕鬆的事 -- 正如它所發生的那樣,對於 Python 來講,檔案控制代碼僅僅是記憶體管理的對象,且該對象由計數器引用。當該引用變為無效時,Python 知道,並會清除它,這時檔案會自動關閉。也有不能完全信任情形(檔案不能自動關閉),例如,您將再次開啟已寫的檔案,並讀它。這時,您要明確地關閉它。這個問題就是無用資訊收集的問題(非 C 的人喜歡討論的問題)。
載入/儲存函數的另一個有趣的特性是他們會碰到由壞檔案調用產生的例外( IOError 例外)。我讓代碼來說明自己,但那是您如何做的,孩子們。
新代碼剩下的問題是事件處理常式,用於處理在程式執行過程中所碰到的。我再次讓程式自己來說明大部分。注意,使用一般的對話方塊( wxMessageDialog 、 wxFileDialog 和 wxTextEntryDialog )來處理許多常規使用者互動。這些調用與“常規”Windows 編程的相應用法有一點不同,這裡我只給您一些線索:首先,對話方塊是一個由合理的調用建立的對象,它用ShowModal() 顯示,用完後並破壞它;其次,使用者單擊的按鈕作為傳回值從 ShowModal() 返回,用對話方塊附屬的方法可得到其它值。例如,在檔案對話方塊互動期間,使用者選擇的路徑是作為 dlg.GetPath() 而獲得。這與 Windows API 的工作方式相當不同。正是這樣您知道的。
文檔狀況
讓我說,wxWindows API 的文檔處於……開發中。這個平台最大的弱點是缺乏好的文檔,我正在積極地改變這種狀況。下半年情況會有所好轉。同時,Python 本身有一些好的書籍,其中 Python 的線上文檔就不差。對於 wxWindows,C++ 的文檔很好。有時,在 Python 架構中,如何使這些文檔合理些,是相當神秘的。在那裡,有一些具體的 Python 注釋,但在很多情況下,您會發現必須要讀隨 wxPython 一起的示範代碼,或者,必須向郵件清單中的專家詢問您的問題。幸運地是,這些專家是“有跡可尋”的。
一旦通過了最初的學習曲線,您會覺得這要比在 Windows API 中做同樣的任務要簡單的多。相信我,這份材料是很好的。
參考資料
- 關於 wxWindows 的介紹,請參閱 developerWorks上的 “細述 wxWindows”。
- wxPython 首頁 連結到該文檔、下載和相關網站。該網站的鏡像在 SourceForge ,它已經連結到 wxWindows 相關人員、wxPython 郵件清單等等。您也可以在這下載 wyPython。
- 在 Python 語言網站 上找到有關 Python 語言的下載、最新開發和文檔。
- Programming Python Mark Lutz 著 (O'Reilly, 1996),ISBN 1-56592-197-6,是我使用 Python 的參考書。它與其說是一本參考書還不如說是一份教程,它是我到目前為止發現的最好的一本書。
- 如果您想動動腦筋,可以閱讀 Christian Tismer 的 Stackless Python,它有效實現了協同常式、發生器、延續和微線程。如果承受不了這種腦力運動,請不要輕易嘗試。
- Vaults of Parnassu 的 Python 資源 是最好的常規初學者園地,以獲關於 Python 中基於文本的使用者介面工具的資訊。
- Python.net 是用於 .NET 的 Python 的開發園地。
- 在三月份舉行的 Ninth International Python Conference。
- 閱讀 JPython: the Felicitous union of Python and Java, Learning Python(O'Reilly, 1999) 一書的摘錄。
關於作者
|
|
|
Michael Roberts 從事編程已有十三年。這篇文章是他幾個月前寫的。您可以給他發 e-mail michael@vivtek.com 或訪問他的網站 www.vivtek.com。 越多越好。 |