0

次の状況を考慮してください。

namespace eval ::mydialog {}

proc ::mydialog::show {w varName args} { 
   upvar 1 $varName theVar
   # now I can access theVar

   # (1)

   # code defining/creating my window
   # here some widgets for user interaction are created, 
   #   some of which will call ::mydialog::_someCallback

   wm protocol $w  WM_DELETE_WINDOW [list ::mydialog::close $w]
}

proc ::mydialog::_someCallback {}  {
   # how do I access theVar here?

   # (2)
}

proc ::mydialog::close { w } {
   # here some changes are supposed to be written back into varName in the calling scope,
   #    how do I do that?!

   # (3)

   destroy $w
}

(a) 呼び出しスコープから変数を取得する方法、(b) 3 つのすべての proc で使用できるようにする方法、および (c) 変更をその変数に書き戻す方法を理解しようとしています。

(a) 通常は 'upvar 1 $varName theVar' を使用して解決します (b) 通常は名前空間変数を使用して解決します (c) (a) で自動的に発生する proc が 1 つしかない限り、その変数のローカルエイリアスに取り組んでいます

問題は、upv​​ar が (少なくとも意図したとおりに) (1) でのみ機能することです。(1) で upvar を使用し、名前空間変数に保存/コピーすると、(a) と (b) は解決できますが、(c) は解決しません。

ここで誰かが私を正しい方向に向けることができれば、私は感謝しています。

また、私は Tcl/Tk に比較的慣れていないため、私のコンセプトは理想的ではない可能性があります。より良い設計に向けた提案も歓迎します。

4

1 に答える 1

1

変数の名前を保持する名前空間変数をupvar使用し、グローバル スコープを使用することをお勧めします。

namespace eval ::mydialog {
    variable varName
}

proc ::mydialog::show {w _varName args} { 
    variable varName $_varName
    upvar #0 $varName theVar

}

proc ::mydialog::_someCallback {}  {
    variable varName
    upvar #0 $varName theVar
    puts $theVar
}

proc ::mydialog::close { w } {
    variable varName
    upvar #0 $varName theVar
    set theVar newval
}

set globalvar oldval
# => oldval
::mydialog::show {} globalvar
::mydialog::_someCallback
# => oldval
::mydialog::close {}
# => newval
puts $globalvar
# => newval

構文の強調表示が失敗することに注意してください#0 $varName theVar。実際にはコメントではありません。

nsvarこれは名前空間変数でも機能します。名前空間で呼び出される変数がある場合は、次の::foobarように使用できます。

set ::foobar::nsvar oldval
::mydialog::show {} ::foobar::nsvar
::mydialog::_someCallback
::mydialog::close {}
puts $::foobar::nsvar

同じ効果で。

ただし、この方法で一部のプロシージャにローカルな変数を使用することはできません。

これを本当に簡単にする 1 つの方法は、Tcl プロシージャのコレクションの代わりに Snit ウィジェットを使用することです。

ドキュメント: namespaceprocputssetupvarvariable

Snit のドキュメント: man pagefaq (faq は一種の紹介としても機能します)

于 2014-08-18T15:31:50.020 に答える