動的にウィジットを作成する


Ruby/Tk

動的にウィジットを作成する

スクリプトが動作してから、データを読み取り、それを元にしてウィジットを作成したい場合が多々ある。
これにはどうしたら良いのか、やり方を模索する。

ラベルの作成

TkLabel.new {
  text 'Hello World'
  pack('fill' => 'x')
}

とする事でラベルが作成される。
これで、確かにラベルは表示されるんだけど……。
一体どうやってラベルを管理しているんだろう。
後からラベルのテキストを変更したりするには、どうしたら良いんだろうか?

別の方法を見つけた。 それはconfigureを使う方法。

l = TkLabel.new.pack
l.configure('text', 'Hello World')

これならば、ウィジットを生成し、配列に保存しておけば良さそうだ。
必要がなくなったら、配列を削除して新たに作り直してしまえば動的に操作出来る。

require 'tk'

$label_info = Array.new
$cnt = 1

def label_make
	$label_info.clear

	for cnt in 0..$cnt do
		l = TkLabel.new.pack
		l.configure('text', "#{cnt}")
		$label_info.push(l)
	end

	$cnt = $cnt + 1
	Tk.after 1000, proc{label_make}
end

label_make
Tk.mainloop

簡単に解説。
$label_info は、ラベルを格納するためのArrayオブジェクト用の変数。これに作成したラベルオブジェクトを格納していく。
def label_makeは、ラベルを作成するための関数。タイマを使用して一定間隔ごとに呼び出されるようにする。 def label_makeの中身は、 ・最初に配列をクリアする。 ・タイマ処理で呼び出された回数分だけ、ラベルを作成する。 ・作成したラベルの表示文字列を設定。 ・作成したラベルオブジェクトを配列に格納する。

実際に動かしてみると、ラベルが順番にじゃなくて、どんどん増えていく。
ああ、当たり前だ。配列をクリアしたからって、作ったウィジットまでなくなってるわけじゃないんだから。
と言うことになると、作ったラベルオブジェクトをちゃんと破棄する必要がある。
それにはどうするか、destroyすれば良いことが分かった。
つまり、配列をクリアする前に、作ったラベルをdestroyしちゃえば良いと。

require 'tk'

$label_info = Array.new
$cnt = 1

def label_make
	 $label_info.each {|label|
		 label.destroy
	 }
	$label_info.clear

	for cnt in 0..$cnt do
		l = TkLabel.new.pack
		l.configure('text', "#{cnt}")
		$label_info.push(l)
	end

	$cnt = $cnt + 1
	Tk.after 1000, proc{label_make}
end

label_make

Tk.mainloop

edit

最新の20件

2020-11-14 2011-02-12 2006-09-22 2006-05-08 2006-04-22 2006-04-21 2006-04-17 2006-04-05 2006-03-23 2006-03-22 2006-03-21 2006-03-15 2006-01-26 2006-01-23 2005-10-21 2005-10-17