Instantly share code, notes, and snippets.

Embed
What would you like to do?
Tiny snit migration guide for tcltk programmers
#!/usr/bin/wish
# ボタンを作る
pack [button .b1 -text "Push Me!" -command [list Run ls -C]]
# テキスト領域を作る
pack [text .console -height 8] -fill both -expand yes
# callback 手続きを実装する
proc Run args {
.console insert end [exec {*}$args]\n
.console see end
}
#!/usr/bin/wish
# ボタンを作る
pack [button .b1 -text "Push Me!" -command [list Run ls -C]]
# テキスト領域を作る(スクロールバー付き)
package require BWidget
ScrolledWindow .sw
.sw setwidget [text .sw.console -height 8]
pack .sw -fill both -expand yes
# callback 手続きを実装する
proc Run args {
.sw.console insert end [exec {*}$args]\n
.sw.console see end
}
#!/usr/bin/wish
# テキスト領域を作る(スクロールバー付き)
package require BWidget
ScrolledWindow .sw
set myConsole [text .sw.console -height 8]
.sw setwidget $myConsole
pack .sw -fill both -expand yes\
-side bottom
# ボタンを作る
pack [button .b1 -text "Push Me!" -command [list Run $myConsole ls -C]]\
-side top
# callback 手続きを実装する
proc Run {myConsole args} {
$myConsole insert end [exec {*}$args]\n
$myConsole see end
}
#!/usr/bin/wish
# ボタンを作る
pack [button .b1 -text "Push Me!" -command [list Run ls -C]]
# テキスト領域を作る(スクロールバー付き)
package require BWidget
ScrolledWindow .sw
set myConsole [text .sw.console -height 8]
.sw setwidget $myConsole
pack .sw -fill both -expand yes
# callback 手続きを実装する
proc Run args {
global myConsole
$myConsole insert end [exec {*}$args]\n
$myConsole see end
}
#!/usr/bin/wish
# ツールバー用のフレームを作る
pack [set bf [frame .bf]] -fill x
# OK/NG を出すラベルを作る
pack [set myOkNg [label $bf.l1 -text "OK"]] -side left
# ボタンを作る
pack [button $bf.b1 -text "Push Me!" -command [list Run ls -C]] -side left
# テキスト領域を作る
package require BWidget
ScrolledWindow .sw
set myConsole [text .sw.console -height 8]
.sw setwidget $myConsole
pack .sw -fill both -expand yes -side top
# callback 手続きを実装する
proc Run args {
# XXX: 各 callback に、参照する widget 全ての global 宣言が必要になる→増えると大変
global myConsole
global myOkNg
set err [catch {exec {*}$args} result]
$myConsole insert end $result\n
$myConsole see end
if {$err} {
$myOkNg configure -text "NG" -background red
} else {
$myOkNg configure -text "OK" -background gray85
}
}
#!/usr/bin/wish
# snit をロードする
package require snit
# 自作widget `myapp` を定義する
snit::widget myapp {
# テキスト領域を保持するためのインスタンス変数を宣言する
variable myConsole
# widget の実体化の際に呼ばれる手続きを実装
constructor args {
# ボタンを作る
pack [button $win.b1 -text "Push Me!" -command [list $self Run ls -C]]
# テキスト領域を作る
set myConsole [text $win.console -height 8]
pack $myConsole -fill both -expand yes
}
# callback メソッドを実装する
method Run args {
$myConsole insert end [exec {*}$args]\n
$myConsole see end
}
}
# おまけ: このファイルをライブラリ兼コマンドにするための、条件分岐
if {![info level] && $::argv0 eq [info script]} {
# コマンドとして実行した時は、自作 widget `myapp` を .win として実体化・レイアウト
pack [myapp .win] -fill both -expand yes
} else {
# source した時は `myapp` の定義のみで終了
}
#!/usr/bin/wish
package require snit
snit::widget myapp {
variable myConsole
constructor args {
# ボタンを作る
pack [button $win.b1 -text "Push Me!" -command [list $self Run ls -C]]
# テキスト領域を作る(スクロールバー付き)
package require BWidget
set sw [ScrolledWindow $win.sw]
pack $sw -fill both -expand yes
set myConsole [text $sw.console -height 8]
$sw setwidget $myConsole
}
# callback メソッドを実装する
method Run args {
$myConsole insert end [exec {*}$args]\n
$myConsole see end
}
}
if {![info level] && $::argv0 eq [info script]} {
# このファイルを実行した時だけ、myapp を .win として作る
pack [myapp .win] -fill both -expand yes
} else {
# source した時は実行しない。
}
#!/usr/bin/wish
package require snit
snit::widget myapp {
# ここで宣言した変数は全メソッドでアクセス可能に
variable myOkNg
variable myConsole
constructor args {
# ツールバー用のフレームを作る
pack [set bf [frame $win.bf]] -fill x
# OK/NG を出すラベルを作る
pack [set myOkNg [label $bf.l1 -text "OK"]] -side left
# ボタンを作る
pack [button $bf.b1 -text "Push Me!" -command [list $self Run ls -C]] -side left
# テキスト領域を作る(スクロールバー付き)
package require BWidget
set sw [ScrolledWindow $win.sw]
pack $sw -fill both -expand yes
set myConsole [text $sw.console -height 8]
$sw setwidget $myConsole
}
# callback メソッドを実装する
method Run args {
set err [catch {exec {*}$args} result]
$myConsole insert end $result\n
$myConsole see end
if {$err} {
$myOkNg configure -text "NG" -background red
} else {
$myOkNg configure -text "OK" -background gray85
}
}
}
if {![info level] && $::argv0 eq [info script]} {
# このファイルを実行した時だけ、myapp を .win として作る
pack [myapp .win] -fill both -expand yes
} else {
# source した時は実行しない。
}
#!/usr/bin/wish
package require snit
package require BWidget
snit::widget myapp {
# widget オプションの宣言。 options(-exec) でアクセス可能
option -exec [list ls -C]
# ここで宣言した変数は全メソッドでアクセス可能に
variable myOkNg
variable myConsole
constructor args {
# ツールバー用のフレームを作る
pack [set bf [frame $win.bf]] -fill x
# OK/NG を出すラベルを作る
pack [set myOkNg [label $bf.l1 -text "OK"]] -side left
# ボタンを作る
pack [button $bf.b1 -text "Push Me!" -command [list $self Run]] -side left
# テキスト領域を作る(スクロールバー付き)
set sw [ScrolledWindow $win.sw]
pack $sw -fill both -expand yes
set myConsole [text $sw.console -height 8]
$sw setwidget $myConsole
# 実体化時の引数列を options 配列へ代入
$self configurelist $args
}
# callback メソッドを実装する
method Run args {
# 引数が渡されない時はオプション `-exec` の内容を用いる
if {$args eq ""} {
set args $options(-exec)
}
set err [catch {exec {*}$args} result]
$myConsole insert end $result\n
$myConsole see end
if {$err} {
$myOkNg configure -text "NG" -background red
} else {
$myOkNg configure -text "OK" -background gray85
}
}
}
if {![info level] && $::argv0 eq [info script]} {
# このファイルを実行した時だけ、GUI を実体化
# 起動時の引数として渡されたディレクトリ毎に、タブを作る
# global 変数を無駄に増やさないため, apply を使う
apply {{{dir "/"} args} {
# タブの親
pack [ttk::notebook .win] -fill both -expand yes
foreach dir [list $dir {*}$args] {
# タブの中に `myapp` を実体化
.win add [myapp .win.n[incr i] -exec "ls -C $dir"] -text "$dir "
# XXX: タブの最後の文字が隠れるケースが有ったので、末尾にスペースを足した:-<
}
}} {*}$::argv
} else {
# source した時は実行しない。
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment