MBVK 版 Tcl::Tk for perl 的特別說明


取得Perl 版的 Tk 之二: MBVK 的 Tcl::Tk

在 perl 底下使用 Tk, 另一條路是從 Vadim Konovalov 的網頁找到 Tcl-0.* 與 Tcl-Tk-0.* 兩個模組, 下載並安裝。 原始作者是 Malcolm Beattie; 現在則由 Vadim Konovalov 維護。 他採取的方式是直接連結 Tcl 語言 (或其擴充套件) 的 interpreter, 所以具有以下優點:

  1. 如果出現新版的 Tcl 語言 (或其擴充套件), 只需要重新編譯, 就可享用新功能, 不必等待 Vadim Konovalov 更新他的介面程式。
  2. 輕薄短小 -- 兩個模組加起來不到 1MB
  3. 可以顯示中文

特別是第一點非常重要: 因為 Tcl 有很多擴充套件, 例如 Tix 或 incrTcl 等等; 但如果我們採用 nis 版, 卻不一定能夠使用, 而必須看 Nick Ing-Simmons 是否有空也更新他的介面程式。 第二點的影響, 除了節省硬碟空間之外, 也讓 Vadim Konovalov 更容易維護他的介面程式, 有利於這個套件的除錯與永續發展。

當然, 這個版本也有缺點。 他的程式碼較新, 還並不成熟; 版本更新時, 需要隨之安裝的一些相依套件也經常採用最新版 (所以要自己編譯等等); 欠缺書籍與說明文件; 查手冊時, 必須查 Tcl/Tk 的手冊, 並自行理解轉成 perl 的語法。

安裝:

  1. 先確認系統內已安裝 perl。 MS Windows 用戶可以安裝 cygwin, 裡面就有 perl。
  2. 從 CPAN 網站的 Vadim Konovalov 目錄下取得 Tcl 套件與 Tcl-Tk 套件。 由於 Vadim Konovalov 一直在更新, 有時會出現 Tcl 與 Tcl-Tk 版本不一致, 或是需要使用最新版 Tk 等等問題。 這裡示範的是: 2006 年 11 月釋出的 Tcl-0.91 與 Tcl-Tk-0.92, 在 Mandriva 2006.0 作業系統下, 使用 tcl-8.4.11 及 tk-8.4.11 兩個內建的 rpm 套件 (太舊, 欠缺 tile 模組) 的安裝方式。
  3. 先到 rpmfind 下載並安裝 perl-devel 套件。 不然等一下編譯時會出現 "找不到 CORE/EXTERN.h" 之類的錯誤訊息。
  4. 解壓縮之後, 在 Tcl 目錄內, 依序下:
            perl Makefile.PL
            make
            make install            # 這句話必須用 root 身份執行
    

    並注意每一句之後是否出現錯誤訊息? 如果在第一步就已經找不到所需的函式庫 (例如 tcl 或 tk), 再往下做也沒有意義。 如果忽略錯誤訊息執意往下做, 安裝錯誤的版本, 甚至會讓後來安裝 Tcl-Tk 的過程出現更難理解的錯誤訊息。 至於出現在第二步驟編譯過程的警告訊息 ("warning ..."), 通常都沒有什麼關係。

  5. 對 Tcl-Tk 模組重複上一步驟。 至此, 若執行 perl -MTcl::Tk -e '' 應該沒有錯誤訊息, 表示安裝成功。 已可執行簡單的程式, 例如 helloadd
  6. 但若測試稍微複雜的程式, 例如 Tcl-Tk 所附的 demos/wcolors.pl 則出現 "找不到 snit" 的錯誤訊息。 原來還需要相依套件 tcllib。 不過上 rpmfind 所找到的版本也是太舊, 會出現其他問題。 直接 google "tcllib download" 找到 tcllib 下載點, 解壓縮後照 README 指示, 執行 installer.tcl 安裝完成。
  7. 再度執行 demos/wcolors.pl 時, 出現 "找不到 widget::scrolledwindow" 的錯誤訊息。 一樣經過一翻折騰, 最後還是找到同一頁的最新版 tklib, 相同方式安裝完成。
  8. 接下來是找不到 "tile"。 再 google "tile download" 找到 tile 下載網頁。 根據 README.txt 編譯並安裝。
  9. 至此, 應該可以執行 demos/wcolors.pl。 成功之後, 再進入 tk-demos 子目錄, 執行 widget, 幾乎已經把 tk 的所有範例都執行起來了!

查手冊

以下談的是 Tcl-0.72 版及 Tcl-Tk-0.72 版...

mbvk 版的 Tcl::Tk 只是一層非常輕薄短小的介面, 並沒有它自己的手冊; 有問題就直接查原始 Tcl/Tk 的手冊。 大多數時候, 只要將 Tcl/Tk 的手冊/書籍/線上文件的範例程式碼直接翻譯成 perl 語法就可以了。 例如:

  1. 在 Tcl/Tk 裡面, 多數函數的參數與傳回值都是簡單的字串; 那麼在 mbvk 版的 Tcl::Tk 裡面也一樣。
  2. 有些函數在 Tcl/Tk 裡傳回一個 list, 例如不加參數的 configure; 那麼在 mbvk 版的 Tcl::Tk 裡面, 傳回值就是一個陣列。
  3. 在 Tcl/Tk 裡面, 函數的名字可以當做參數來傳遞, 效果等同於傳遞函數的位址, 例如建立按鈕時在 -command 後面指定 event handler; 那麼在 mbvk 版的 Tcl::Tk 裡面, 則要改成 perl 的語法, 傳遞函數的 位址

比較特別的是如何呼叫函數。 Tcl/Tk 裡面, 很多函數都是為某個視窗元件呼叫的, 必須寫在 widget 的 pathname 之後, 例如 .greetings configure ...。 這在 mbvk 版的 Tcl::Tk 裡面, 則很自然地改成物件導向的寫法: widget(".greetings")->configure(...)。 當然對 perl 而言, ".greetings" 只是一個字串, 所以必須先用一個函數 widget 查出對應於此的物件。


自由穿梭於 perl 語法與 tcl 語法之間

(建議初學者略過此節) mbvk 版有一個特點: 你的程式可以寫成 nis (perl-Tk) 風格, 也可寫成 tcl 風格。

讀者會選擇 perl 版的 Tk 而不是 Tcl/Tk, 大概就是因為覺得 perl 比 Tcl 好用。 因此, 平時程式, 用 nis (perl-Tk) 風格比較方便。 ...

講義主體中, 幾乎可以用一個範例程式同時教 nis 版與 mbvk 版, 就是因為所有的 perl 範例都用 nis (perl-Tk) 風格所寫。 少數地方 mbvk 版與 nis 版不同的寫法, 藏在特定格式的註解裡面。 ...

何時需要用到 tcl 風格? 如果用到 Tk 之外的 widgets, 例如 Tix, ... 或是大量用到其他 tcl 指令, ...


其他議題

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 才是你的版本的範例程式。 其實也可以直接執行, 不過裡面有一些被註解掉, 與你無關的程式碼。

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