Ruby/Tk:ウィンドウを増やすテスト

ボタンをクリックするたびにウィンドウを追加する方法を調べてみました。

参考書

Ruby/Tkについて、とても参考になる記述が多い本が手元にあったので、順を追って読み進めています。

Rubyアプリケーションプログラミング

Rubyアプリケーションプログラミング

TkToplevel

上述した参考書「Rubyアプリケーションプログラミング」のp300にルートウィジェット等の説明があります。ここにトップレベウィジェット(TkToplevel)について次のように書かれています。

トップレベウィジェットは、「新たなウィンドウとして作成される」という重要な点を除き、フレームウィジェットと同じです。新たなルートウィジェットといってもよいでしょう。

つまりこれを使えば新しくウィンドウを作ることは簡単に出来そうだ。
また、TkToplevelクラスについては、ソース(自分の環境の場合、C:/ruby/lib/ruby/1.8/tk/toplevel.rb)を見ると簡単な使い方は想像できる。

class TkToplevel<TkWindow
  # -- 略 -- #
  def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
    # -- 略 -- #
      @classname = keys['class']
      @colormap  = keys['colormap']
      @container = keys['container']
      @screen    = keys['screen']
      @use       = keys['use']
      @visual    = keys['visual']
  # -- 略 -- #
end

ウィンドウのタイトルは変更できないのかな?

コード

以上のようにあれこれ調べて、実際に動作に成功したコードを以下に載せておきます。
ウィンドウそれぞれについて何か処理を行いたくなるのは目に見えているので、簡単なクラスを定義しています。

#!/usr/bin/env ruby

require 'tk'

#----------------------------------------
# クラス定義.
#----------------------------------------

# ウィンドウクラス.
class CWindow
  @tkwin # このオブジェクトが持つTkウィンドウ.
  @name  # このウィンドウの名前.
  def initialize( index )
    @name  = index.to_s
    @tkwin = TkToplevel.new()
    p "init CWindow[#{@name}]"
    TkLabel.new( @tkwin, 'text'=>'Window #'+@name ).pack
  end
end

# ウィンドウ管理クラス.
class CWindowManager < Array
  def initialize()
    p "init CWindowManager"
  end
end


#----------------------------------------
# グローバル変数.
#----------------------------------------

$windows = CWindowManager.new


#----------------------------------------
# 基本となるRootウィンドウの設定.
#----------------------------------------

# ボタン:ウィンドウの数を確認.
TkButton.new(
  nil,
  'text'=>'NumOfWindows',
  'command'=>proc{ p $windows.length }
).pack

# ボタン:ウィンドウを追加.
TkButton.new(
  nil,
  'text'=>'ADD WINDOW!',
  'command'=>proc{
    $windows.push( CWindow.new($windows.length) )
  }
).pack


#----------------------------------------
# メインループ.
#----------------------------------------

Tk.mainloop