這一篇文章介紹Tk的事件處理方法。預設Tk已經為許多視窗元件加上了捕捉事件的選項。例如:按鈕的-command選項可以用來捕捉滑鼠的點擊(Click)事件,一但捕捉到事件,指定給-command選項後面的程式片段就會被執行。雖然Tk已經在各種視窗元件中提供了足夠的事件處理的選項,但有時候我們還是會想要處理更細節一點的事件,例如:希望滑鼠滑過某個視窗元件時做某些事,或是某個視窗元件大小被改變、顯示及隱藏時做某些事,此時我們就需要使用bind命令來幫忙,才可以完成這些較細節的事件動作。
36.1 bind命令及鍵盤、滑鼠事件
TK的bind命令可以用來設定視窗元件綁定某些事件,它的語法如下:bind tag ?sequence? ?script?
上面tag的位置可以放視窗元件的path或是某個視窗元件的類別,sequence放需要綁定的事件描述,最後的script放事件發生要執行的程式碼。以下是一個簡單的例子,我讓標籤元件,綁定「滑鼠壓下」、「滑鼠滑過」及「滑鼠放開」的事件,如果你想要做類似VB或是Visual Tcl那樣在表單裡拖放元件的功能,就會需要使用這些事件。
這個例子執行以後會在螢幕上顯示一個標籤元件,你可以試試看用滑鼠左鍵,抓住它然後移動,雖然標籤並不會真的被移動,但-text選項上會反應出正在發生的事件,這可以幫助我們查看事件被觸發的時機。
在上面的例子中ButtonPress-1及ButtonRelease-1的「1」用來表示為滑鼠左鍵,你也可以把它換成2或3,來表示滑鼠的右鍵或中鍵。注意哦!!在不同的作業系統裡2及3與滑鼠鍵的對應關係不見得是一樣的,例如在Linux下2表示為中間,但在Mac下2是表示右鍵。另外,若ButtonPress及ButtonRelease後面不加任何數字,那表示任何一個滑鼠鍵被壓下或是放開都會觸發事件。
下以是另一個例子,在這個例子中我把Ctrl+滑鼠左鍵點擊設定為要綁定的條件。
這個例子要說明Button-X表示為某個滑鼠按鈕的Click事件,當然X也可以換成2、3或是其它數字。另一個要說明的是每一個事件的描述像Button、ButtonPress的前面都可以再加上Control、Shift、Meta...等更細節的修飾。以下是描述事件的完整語法:
<modifier-modifier-type-detail>
第一個modifier欄位你可以放Double、Triple、Quadruple、Control、Shift、Alt或Meta,用來表示按鈕重覆的次數或鍵盤上對應的按鍵。第二個modifier可以放Control、Shift、Alt及Meta等描述,而每一個Control、Shift、Alt或Meta這樣的描述還可以分左右邊,例如:Alt_L表示左邊的Alt鍵,Meta_R表示右邊的Meta鍵。第3個欄位用來指定像Button或是Key的事件的類型。最後的detail欄位用來描述各種事件類型的細節。注意哦!! 在大部份的情況下,很多事件是不用modifier欄位及detail的。以下是一些事件描述的例子:
- Enter : 滑鼠滑進某個視窗元件
- Leave : 滑鼠滑出某個視窗元件
- Motion : 滑鼠在某個視窗元件上滑動
- FocusIn : 游標停駐點進入某個視窗元件
- FocusOut : 游標停駐點由某個視窗元件移出
- Button-X : 某個滑鼠鍵的點擊事件
- ButtonPress-X : 某個滑鼠鍵的下壓事件
- ButtonRelease-X : 某個滑鼠鍵的放開事件
- Double-Button-X : 某個滑鼠鍵的雙擊事件
- Control-Button-X : Ctrl+某個滑鼠鍵的點擊事件
- Shift-Button-X : Shift+某個滑鼠鍵的點擊事件
- Alt-Button-X : Alt+某個滑鼠鍵的點擊事件
- Double-Control-Button-X : Ctrl+某個滑鼠鍵的雙點擊事件
以下是另一個可以查看滑鼠事件的例子,請試試看讓你的滑鼠及游標停駐點在下面的兩個文字方塊間移動。
□ 鍵盤事件
鍵盤事件的處理方法和滑鼠事件是大同小異的,請看以下的範例:這個例子幫文字方塊.txt綁定了4個跟按鍵「a」相關的事件,當然你也可以把「a」換成鍵盤上的其它按鍵。
36.2 事件的代換符號
回顧一下bind的語法,如下:bind tag ?sequence? ?script?
我們已經知道script是事件觸發時要執行的程式片斷,而事實上在這些程式片段裡,我們還可以加上一些用%開頭再加一個字元所組成殊特符號,這些特殊的符號會被bind命令代換成有特殊意義的數值,例如:
在上面的例子中,事件觸發的程式片段裡,%W會被代換為綁定這個事件本身的視窗元件,%x及%y會被代換為滑鼠點擊在視窗元件上的x,y座標。所以當你在.lbl上點擊滑鼠左點,就會有類似下方的輸出。
元件:.lbl , 點擊的x座標: 324 , y 座標: 30 元件:.lbl , 點擊的x座標: 246 , y 座標: 195 元件:.lbl , 點擊的x座標: 282 , y 座標: 192
另一個最常用的代換例子是用來顯示右鍵功能表,例如:
這個例子把.txt綁了滑鼠右鍵的事件,並且在事件的程式片段中用%X及%Y代換出滑鼠點擊的位置,然後在這個位置顯示右鍵功能表。注意哦!! %X、%Y和%x、%y的差別在於大寫的XY是以螢幕的左上角為原點,而小寫的xy是以視窗元件的左上角為原點。以下是一些常用的代換符號,更多詳細的代換符號請參考bind命令的手冊。
- %W : 視窗元件本身的path
- %X,%Y : 相對於螢幕左上角的座標
- %x,%y : 相對於視窗元件本身左上角的座標
- %b : 用在滑鼠事件,會被代換成滑鼠按鈕的編號
- %k,%K : 用在鍵盤事件,會被代換成按鍵的keycode及keysym
36.3 其它的事件
以下列出其它常用的事件,及它們的說明,有興趣的朋友可以自己想些例子試看看。- Activate及Deactivate : 這兩個事件會分別在頂層視窗被設定為活動中或非活動中被觸發
- Configure : 這個事件會在視窗元件的大小、位置、邊框寬度及堆疊順序(stack order)被改變時觸發
- Destroy : 這個事件的在視窗元件被銷毀時觸發
- Map : 這個事件會在頂層視窗的狀態被為normal時被觸發
- Unmap : 這個事件會在頂層視窗的狀態被為withdrawn或是iconic時被觸發
- Visibility : 這個事件會在視窗元件變為可視或是被其它視窗遮住時觸發,你可以用%s來代換出目前的狀態
按右上方的「#」號切換側邊欄