2011-07-29 61 views
3

我有一個Tcl腳本控制自動測試儀。到目前爲止,它是一個控制檯程序,它在命令提示符下接受用戶輸入。一位同事寫了一個可以由腳本啓動的Tk GUI。我從來沒有用過Tk,所以我不瞭解很多語法。Tcl/Tk綁定需要全局變量?

在測試開始時,腳本必須從操作員那裏獲得一個單元序列號。這是我的同事寫道做到這一點的功能:

proc GetSerialNumber {} { 
global gUserInterfaceBarCode 

DisplayMessage "Enter serial number:" 

.c.serialnumberbox configure -state normal 

focus .c.serialnumberbox 

bind .c.serialnumberbox <Return> { set gUserInterfaceBarCode [.c.serialnumberbox get] } 

tkwait variable gUserInterfaceBarCode 

#grid forget .c.serialnumberbox 

.c.serialnumberbox configure -state disabled 

} 

DisplayMessage是,只是在GUI更新文本標籤的過程。

我不喜歡這個事實,即有一個全局變量gUserInterfaceBarCode用於保存序列號。有什麼方法可以改用局部變量,並讓程序返回該值?

如果我理解正確,如果行tkwait variable gUserInterfaceBarCode取出,此功能不會阻止,直到該變量更改。這是從GUI元素捕獲用戶輸入的最佳方式嗎?

回答

6

基本上你需要有一個等待的變量。不幸的是,<Return>的代碼是在不同的上下文(全局上下文)中執行的,而不是你的proc中的代碼,並且代碼無法處理你的proc中的局部變量。

但是,它本身並不需要一個全局變量 - 它只需要全局可尋址,我的意思是您可以使用一個名稱空間變量,如果這讓您感覺更好:

namespace eval GetSerialNumber { 
    proc GetSerialNumber {} { 

     DisplayMessage "Enter serial number:" 
     .c.serialnumberbox configure -state normal 
     focus .c.serialnumberbox 
     bind .c.serialnumberbox <Return> { set ::GetSerialNumber::result [.c.serialnumberbox get] } 
     tkwait variable ::GetSerialNumber::result 
     .c.serialnumberbox configure -state disabled 
     return $::GetSerialNumber::result 
    } 
} 

set serialNum [GetSerialNumber::GetSerialNumber] 

另一種方法是在返回前顯式刪除gUserInterfaceBarCode

tkwait variable ::gUserInterfaceBarCode 
set result $::gUserInterfaceBarCode 
unset ::gUserInterfaceBarCode 
return $result 

對於它的價值,Tk的核心實現使用的命名方式具有自己的內置對話框的實現,如「開放文件「對話框。

+1

Tk腳本還會在其自己的幫助程序中將任何事情變得模糊不清,因爲它更容易處理範圍。 –

+0

由於大多數Tcl OO擴展允許對象實例變量看起來像名稱空間變量,所以您還可以使用OO擴展來封裝變量。第三種方法是爲所有狀態使用一個全局數組變量,而不是爲每個值使用一個變量名稱。 – schlenk