ルモーリン
ホーム更新サービス雑談ランドナーコースガイド鉄ゲタ自転車Linuxリンク連絡先

リストボックスのイベントを拾う

目的

行をダブルクリックして設定を変えるような動作を作りたい。 ところがリストボックスをダブルクリックしてもプログラムは分からず、当然のことながらどこをダブルクリックしたかも分からない。 こいつを何とかしたい。

Tcl/Tkの書き方

こちらのサイトを参考にしました。→ Tcl/Tk お気楽 GUI プログラミング入門編
参考にした書き方がこちら。
bind .lb <Double-1> {
	~
}
それと
.lb curselection
で選択した行が返るようです。

Perl/Tkxの書き方

コマンド名+ウィジェット名+パラメタの場合は「"ウィジェットの変数"->g_"コマンド名"(パラメタ)」で呼べます。 呼び出すサブルーチンdouble_clickの第1引数にウィジェットを渡して操作できるようにします。
$lbx->g_bind(
	"<Double-1>" => [\&double_click, $lbx, ],
);
ウィジェット名+コマンド名の場合は「"ウィジェットの変数"->"コマンド名"」で呼べます。
$lbx->curselection;

スクロールバー付きリストボックス

手軽にスクロールバーを付けられるのでリストボックスはこれを使っています。
Tkx::Scrolled - Tkx megawidget for scrolled widgets - metacpan.org
ところがイベントを拾う際にこのリストボックスを指定するとイベントが伝わりません。
生成されるウィジェットがリストボックスそのものではないらしく、そこにダブルクリックをバインドしてもイベントを受けられません。 子の中に「scrolled」というウィジェットがあり、これがリストボックス自体のようで、ここにバインドします。
$lbx->_kid("scrolled")->g_bind(
	"<Double-1>" => [\&double_click, $lbx, ],
);

全体のコード

動作するコードは次のようになります。
#!/usr/bin/perl -w

use utf8;
use strict;
use warnings;
use open IO => ":utf8";

use v5.10;
use Encode::Locale;
use Tkx;
use Tkx::Scrolled;

binmode STDOUT, ":encoding(console_out)";
binmode STDIN, ":encoding(console_in)";

$| = 1;

$Tkx::TRACE = 1;

my $mw = Tkx::widget->new(".");

my $lbx = $mw->new_tkx_Scrolled(
	"listbox",
	-selectmode => "single",
	-scrollbars => "e",
	-width => 20,
	-height => 10,
	-activestyle => "none",
);
$lbx->g_pack(-anchor => "w");

$lbx->_kid("scrolled")->g_bind(
	"<Double-1>" => [\&double_click, $lbx, ],
);

$lbx->insert("end", "item $_") for (0 .. 19);

Tkx::MainLoop();

exit;

sub double_click {
	my ($lbx) = @_;
	my ($idx) = $lbx->curselection;
	say "click $idx";
}

実行結果

Perl/Tkxのトレースがエラー出力に出すよう「$Tkx::TRACE = 1;」を実行しています。 起動後にリストボックスの5行目をダブルクリックした場合のトレース結果がこちらになります。 おそらくTcl/Tkのコマンドだと思います。 Perl/Tkxと見比べて参考にしてください。
Tkx-1-0.0s-sample_tkx_7.pl-22: winfo children .
Tkx-2-0.0s-sample_tkx_7.pl-22: package require tile
Tkx-3-0.0s-sample_tkx_7.pl-22: ttk::frame .t -class Tkx_Scrolled
Tkx-4-0.0s-sample_tkx_7.pl-22: listbox .t.scrolled -width 20 -height 10 -selectmode single -activestyle none
Tkx-5-0.0s-sample_tkx_7.pl-22: ttk::scrollbar .t.xscrollbar -orient horizontal
Tkx-6-0.0s-sample_tkx_7.pl-22: ttk::scrollbar .t.yscrollbar -orient vertical
Tkx-7-0.0s-sample_tkx_7.pl-22: .t.xscrollbar configure -command [list .t.scrolled xview]
Tkx-8-0.0s-sample_tkx_7.pl-22: .t.yscrollbar configure -command [list .t.scrolled yview]
Tkx-9-0.0s-sample_tkx_7.pl-22: .t.scrolled configure -xscrollcommand perl::callback
Tkx-10-0.0s-sample_tkx_7.pl-22: .t.scrolled configure -yscrollcommand perl::callback
Tkx-11-0.0s-sample_tkx_7.pl-22: grid .t.scrolled -row 1 -column 1 -sticky nsew
Tkx-12-0.0s-sample_tkx_7.pl-22: grid .t.yscrollbar -row 1 -column 2 -sticky ns
Tkx-13-0.0s-sample_tkx_7.pl-22: grid columnconfigure .t 1 -weight 1
Tkx-14-0.0s-sample_tkx_7.pl-22: grid rowconfigure .t 1 -weight 1
Tkx-15-0.0s-sample_tkx_7.pl-30: pack .t -anchor w
Tkx-16-0.0s-sample_tkx_7.pl-32: bind .t.scrolled <Double-1> perl::callback
Tkx-17-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 0}
Tkx-18-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 1}
Tkx-19-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 2}
Tkx-20-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 3}
Tkx-21-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 4}
Tkx-22-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 5}
Tkx-23-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 6}
Tkx-24-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 7}
Tkx-25-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 8}
Tkx-26-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 9}
Tkx-27-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 10}
Tkx-28-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 11}
Tkx-29-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 12}
Tkx-30-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 13}
Tkx-31-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 14}
Tkx-32-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 15}
Tkx-33-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 16}
Tkx-34-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 17}
Tkx-35-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 18}
Tkx-36-0.0s-sample_tkx_7.pl-36: .t.scrolled insert end {item 19}
Tkx-37-0.1s-Tcl.pm-518: .t.yscrollbar set 0.0 0.5
Tkx-38-0.1s-Tcl.pm-518: .t.xscrollbar set 0.0 1.0
Tkx-39-10.7s-sample_tkx_7.pl-44: .t.scrolled curselection
click 5