hakeの日記

Windows環境でプログラミングの勉強をしています。

Ruby/Tk サブウィンドウの作成

サブウィンドウ用のメソッドopen_sub_windowを作成して、このメソッド内でサブウィンドウのウィジェットを配置して作成します。
ルートウィンドウ側との情報のやり取りについて、最初はメソッドの引数と返り値で行おうとしましたが、メソッド自体は直ぐに終了してしまうため不可でした。この為グローバル変数$swによって行う様にします。

サブウィンドウのベースはTkToplevelを使用します。またサブウィンドウを開いている間にルートウィンドウへの操作を不可にするために、TkToplevel#grab_setを実行します。サブウィンドウ閉じるときは、TkToplevel#destroyを実行。

#coding: Windows-31J
require "tk"

# サブウィンドの設定を保存する変数
$sw = TkVariable.new_hash
# 初期設定
$sw[:status] = :INIT
$sw[:entry]  = ''
#$sw[:radio]  = 'item_r0'
$sw[:radio]  = ''
$sw[:check0] = '1'
$sw[:check1] = '0'
$sw[:check2] = '0'

#
# Sub Window
#
def open_sub_window
p 'method start'

  $sw[:status] = :OPEN
  base = TkToplevel.new(nil, title: 'Sub Window')
  # Root Windowの操作を禁止する
  base.grab_set

  e = TkEntry.new(base).pack(side: :top, fill: :x)
  e.value = $sw[:entry]
  flame = TkFrame.new(base).pack
  f_left  = TkLabelFrame.new(flame) do
    text('RadioButton')
    pack(side: :left)
  end
  f_right = TkLabelFrame.new(flame) do
    text('CheckButton')
    pack(side: :left)
  end
  TkButton.new(base) do
    text('close')
    # Entry入力文字を$swにコピーしてから、ウィンドウを閉じる
    command( proc do
               $sw[:entry]  = e.value
               $sw[:status] = :CLOSE
               base.destroy
             end
    )
    pack(fill: :x)
  end

  3.times.each do |i|
    TkRadioButton.new(f_left) do
      text  "item_r#{i}"
      value "item_r#{i}"
      variable $sw.ref(:radio)
      select if i == 0          # 初期設定
      pack(side: :top)
    end
  end

  TkCheckButton.new(f_right, text:'item_c0', variable: $sw.ref(:check0)).pack
  TkCheckButton.new(f_right, text:'item_c1', variable: $sw.ref(:check1)).pack
  TkCheckButton.new(f_right, text:'item_c2', variable: $sw.ref(:check2)).pack
  
p 'method end'
end

#
# Root Window
#

TkRoot.new.title('サブウィンドウへのアクセス')

txt = TkText.new
txt.pack(side: :top)

btn1 = TkButton.new do
  text('Open Sub Window')
  # サブウィンドウを開く
  command(
    proc do
      open_sub_window
    end
  )
  pack(side: :left, fill: :x)
end

btn2 = TkButton.new do
  text('Result')
  # $swの値を表示する
  command(
    proc do
      txt.value  = "入力した文字は、#{$sw[:entry]}です。\n"
      txt.value += "ラジオボタンは、#{$sw[:radio]}が選択されています。\n"
      txt.value += "item_c0が選択されています。\n" if $sw[:check0] == '1'
      txt.value += "item_c1が選択されています。\n" if $sw[:check1] == '1'
      txt.value += "item_c2が選択されています。\n" if $sw[:check2] == '1'
    end
  )
  pack(side: :left, fill: :x)
end

Tk.mainloop