NIS 版 perl-Tk 的特別說明


取得 NIS 版的 perl-Tk

要在 perl 底下使用 Tk, 至少有兩種不同的方法。 這一節先介紹 nis 版。 這個版本的優點是: 成熟; 有市售書籍可參考; 缺點是: 在 Linux 下, 不支援中文; 每次 Tcl/Tk 更新, 就必須等待 Nick Ing-Simmons 移植新版。 以常用的作業系統為例, 要使用 perl-Tk, 有幾個不同的選擇。

如果懶得安裝或不想動到硬碟, 可以選擇完全不要安裝。 下載 dolphin 版或 mirror 版的 knoppix, 只要將 iso 檔燒成光碟, 並將電腦設定成光碟開機, 重開機之後就可以直接使用。

如果你的作業系統是 Linux, 且套件管理方式是 rpm, 則可以到 rpmfind 取得適當的 perl-Tk 套件。 至於 perl 幾乎一定內建, 不必事先另外安裝。 用 rpm -qi perl 可以確認已安裝, 順便記下 perl 的版本。 下載 perl-Tk 時應如何選擇版本? (1) 檔名中應有 .i386 或 .i586 (2) 最好與 perl 搭配 (3) 如果是 Mandrake 用戶, 最好找檔名當中有 mdk 者 (4) 如果還有得選, 可以選新一點的。 然後下 rpm -U 檔名 安裝。

其他版本的 Linux 或 *BSD 用戶, 可以試著用各種工具將 上述 perl-Tk 的 rpm 轉成你的作業系統的套件格式。 同樣地, perl 幾乎都是內建, 不必事先另外安裝。

Windows 用戶有幾個不同的選擇:

  1. 下載 cygnuwin 光碟 (實為 cygwin 與 gnuwin 的混合體), 裡面有 MS Windows 上所需要的所有套件 (perl 與 perl-Tk), 可以一次安裝完成。 或
  2. 先安裝 cygwin 再安裝 cygwin 版的 perl-Tk。 或
  3. 安裝 ActivePerl 並選擇 perl-Tk 套件。 (很久沒試這條路了, 不要問我啦...) 或
  4. 安裝 舊版 Active Perl

其他作業系統用戶, 請到 官方網站 下載原始碼自行編譯。

不論取得那一個版本, 都應該測試一下。 請開一個文字視窗 (X Window 下的終端機視窗, 或 MS Windows 下的 cygwin 或 bash 視窗), 並且下 perl -MTk -e '' 如果提示符號又出現, 沒有錯誤訊息, 彷彿沒發生任何事情一樣, 那就成功了。 如果出現 "@INCLUDE 內找不到 Tk.pm" 之類的訊息, 那麼有可能是 perl 版本與 perl-Tk 版本不合, 需要改下 perl -I/usr/lib/... -MTk -e '' 其中 -I 後面的路徑你要自己找。

安裝成功後可以執行範例程式 /usr/bin/widget, 讀讀 perl/Tk FAQ (有點舊, 但解答很多有趣的問題) 逛逛 Important Perl/Tk Linkswww.perltk.org 甚至下載一些 用 perl/tk 寫的程式 來玩玩。 Tcl/Tk 的 wiki 網站也有 perl-Tk 資源


查手冊

nis 版的 perl-Tk 有它自己的手冊。 例如 Tcl/Tk 裡面的 label(n) 手冊, 在 nis 版則下 perldoc Tk::Label 又如 button(n) 手冊, 在 nis 版則下 perldoc Tk::Button 等等。 注意凡是 widget class 的名稱, 第一個字母都改用大寫。 至於其他手冊, 則多半與原手冊名稱相同, 例如 Tcl/Tk 裡面的 options(n), 在 nis 版則下 perldoc Tk::options

fpons@mandrakesoft.com 所包的 perl-Tk rpm, 則是將手冊放在系統手冊的 3pm 章。 所以要查上述手冊, 變成查 man 3pm Tk::Label, man 3pm Tk::Button, man 3pm Tk::options等等。


如何有系統地給 widgets 命名?

注意: 此節方法不利於修改成 nis/mbvk 混合版 我個人的習慣是: 為了

  1. 避免取一大堆 widget 變數名稱, 污染變數的命名空間 (namespace)
  2. 每個 widget 的 path name 可以像在 tcl/tk 當中一樣, 從變數名稱就可以看出來

我用 nested anonymous hash, 按照 widget 產生途徑 (parent-child 關係) 來存新產生的 widget. 例如在 一個程式 當中本來要叫做 $w_upper_right 的 widget, 按照 我的寫法 就變成了 $main->{upper}{right}. 因為 perl/tk 建構 widgets 時, 傳回來的正是一個 (blessed) reference to a hash, 所以我們可以這樣做. 此外, perl/tk 會自動指定 widget 的 path name 給新的 widget, 以後這個名字可以用 PathName 這個 widget command 看到 (詳見 perldoc Tk::Widget). 如果你不喜歡內定的名字, 例如你希望它和你的 hash key 或變數名稱相同, 那麼可以在產生這個 widget 時加上 Name 這個 configuration option. 詳見 perldoc Tk::options 當中的 Creation options 一節. 也請參考 relinquish 範例程式當中的幾個 frames 產生的方式。


callback (event handler)

詳見 perldoc Tk::callbacks。

指定 callback, 最簡單的方式 (callback 本身沒有參數):

  1. 給一個 reference to subroutine, 像 marquee 當中 after 的參數 RotateColor 與 RotateText.
  2. 以字串的方式給一個 "內建的 method 名稱"
  3. 給一個 closure (沒有名字的副程式). 詳見 "Advanced Perl Programming", Sriram Srinivasan.

一般情況下 (例如 after, -command, ...), 指定 callback 時, 不給它參數, 未來它被叫起來時, 就不會接收到參數; 但是 bind 則會自動把 "事件發生處" 的那個 widget 當做參數, 傳給 callback, 例如 relinquish 當中 bind 的參數 "complain" 看起來似乎沒有參數, 但其實有.

指定 "callback 被叫起來時, 要接收到那些參數" 的語法: 把 callback (不論是 reference to subroutine, method 名稱, 或是 closure) 和 它自己的參數 一起放在一個陣列中 (通常是一個 anonymous array), 再把這個陣列的 reference 傳給 bind, after, -command, ... 例如

  1. relinquish 當中各個 button 的 -command 的參數 relinquish
  2. memory 當中 bind 的參數 check
  3. chameleon 當中 <Leave> 事件的 callback.

其他議題

  1. 用比較簡潔的方式給視窗加上 scrollbars: 見 perldoc Tk::Scrolled

nis/mbvk 混合版

pl/ 目錄底下的範例程式, 混合 nis/mbvk 兩種版本, 還要再經過一道手續, 才能夠拿來使用。 以 hello 為例:

  1. nis 版的讀者, 請用下列指令: perl -ne 's/^#\s*(.*)#=NIS=#/$1/; print unless /#=MBVK=#/' hello > hello.pl 產生出來的 hello.pl 才是你的版本的範例程式。
  2. mbvk 版的讀者, 請用下列指令: perl -ne 's/^#\s*(.*)#=MBVK=#/$1/; print unless /#=NIS=#/' hello > hello.pl 產生出來的 hello.pl 才是你的版本的範例程式。 其實也可以直接執行, 不過裡面有一些被註解掉, 與你無關的程式碼。

至於有些稍微複雜的程式, 沒有辦法如此共用程式碼, 就要靠一些 低階的副程式 來掩蓋相異之處。