簡単なサンプルとして、チャネルの出力先を text ウィジェットにした例を紹介します。
# -----------------------------------------------------------------------------
# NAMESPASE textOut
# -----------------------------------------------------------------------------
namespace eval textOut {
variable subCmds [list initialize finalize watch write]
variable m; # pathName of text widget to display message
namespace ensemble create -subcommands $subCmds
namespace export regist
# initialize
proc initialize {channelId mode} {
variable subCmds
return $subCmds
}
# finalize
proc finalize {channelId} {
# NOP
}
# watch
proc watch {channelId eventspec} {
# NOP
}
# write
proc write {channelId data} {
variable m
set msgout [encoding convertfrom [encoding system] $data]
$m configure -state normal
$m insert end $msgout
$m see end
$m configure -state disable
update
return [string length $data]
}
# regist
# The namespace specific command to remember pathName
proc regist {pathName} {
variable m
if {![winfo exists $pathName]} {
error "$pathName does not exist."
}
if {[winfo class $pathName] ne "Text"} {
error "$pathName is not text widget."
}
set m $pathName
$m configure -state disable
return $m
}
}
chan create コマンドで利用する、チャネルを操作するコマンド(この例では textOut)では、定められた名前のサブコマンドを用意する必要があります。前回紹介した、namespace ensemble コマンドを利用すると簡単にできます。(これが唯一の方法というわけではありません。)
上記のスクリプトを textOut.tcl というファイル名で保存した後、コンソール上で wish あるいは tclsh を起動、source コマンドで読み込んで実行した例を以下に示します。
$ tclsh
% package require Tk
8.5.6
% pack [text .t]
% source textOut.tcl
% textOut::regist .t
.t
% set out [chan create write textOut]
rc0
% chan configure $out -buffering line
% puts $out "これは出力テストです。"
%
出力先の text ウィジェットのパス名を textOut::regist で名前空間内の変数に登録してから利用します。なお、chan configure コマンドで -buffering line を指定して、バッファに出力が溜まらないようにしています。デフォルトでは、flush しないと(バッファが一杯になるまで)出力はバッファに溜まったままになります。
この例は、特定のチャネルを通じて、text ウィジェットに文字列を出力するだけの簡単なものですが、chan create コマンドによるチャネルの定義は、いろいろ応用できる分野がありそうです。
0 件のコメント:
コメントを投稿