#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- ENV['XMODIFIERS'] = '@im=kinput2' require 'tk' # 起動時に登場するウィジェットと逆の順番で書いてある(変数参照の都合上) # ソースを読むときは下の「ラベル」から上に読んでいくとよい。 fnL = ENV["FONT_M"] || "ipagothic 32" fontL = TkFont.new(fnL) fnM = ENV["FONT_M"] || "ipagothic 24" fontM = TkFont.new(fnM) fnS = ENV["FONT_S"] || "ipamincho 16" fontS = TkFont.new(fnS) # ウィジェットすべてのデフォルトフォントを設定するなら #Tk.tk_call('option', 'add', '*font', fnS) TkOption.add('*font', fnS) ###################################################################### # テキストエリアとメニュー text = TkText.new { # テキスト入力エリア # 初期値を入れる場合は、自身のオブジェクトのvalueに代入しておく self.value = "ここはテキストエリア適当に入力してね。 これは消しちゃってもいいよ。メニューも機能しまっせ。" focus # あらかじめフォーカスを当てておく(ない場合と比較せよ) cursor("gumby") } menu = TkFrame.new {|f| TkMenubar.new(f, [ [['File', 0], ["New Window", proc { TkToplevel.new("title"=>"New Window")}, 4], ["Quit", proc { printf("入力値:[%s]\n", text.value) puts("さようなら") exit 0}, 0]], [["Edit", 0], ["Clear", proc { text.value = ""}, 0], ["Set Title", proc { Tk.root["title"] = text.value }, 0], ['Reverse', proc { text.value = text.value.reverse}, 0]]] ).pack("side"=>"left") } ###################################################################### # リストボックス(TkListbox) # (複数のアイテムリストから任意個のアイテムを選択) choices = %w(北海道 青森県 秋田県 山形県 岩手県 宮城県 福島県) choices += %w(新潟県 長野県 山梨県 群馬県 茨城県 栃木県 埼玉県 千葉県) lblabel = nil # lbframeブロック内部で使う変数宣言 #radioframe=nil lbframe = TkFrame.new {|f| # この局所変数fは新規フレーム自身になる lblabel = TkLabel.new(f).pack howmanylabel = TkLabel.new(f, "text"=>"0個選択").pack TkButton.new(f, "text"=>"さっきの3択やりなおす") { # 1つ前のラジオボタンに戻る処理 # radioframe変数はこの行より下で初めて宣言されるのでここでは # radioframe変数は未定義。radioframe変数のフレームオブジェクトを # ここで使いたい場合は eval にして評価されるのをボタンが押された # 時にずらすか、このブロックより前にradioframe変数を登場させておく。 # ここではevalを用いた。eval使用時は任意コードが実行されないよう注意。 command(proc { f.unpack eval "radioframe.pack"}) }.pack # まずスクロールバーウィジェット作成 # yscrollbarとして使うなら"fill"=>"y" (縦方向精一杯伸ばす) にしておく # "side"=>"right" から右の方から配置する sbar = TkScrollbar.new(f).pack("side"=>"right", "fill"=>"y") # そのスクロールバーとくっつけてリストボックスを作る lb = TkListbox.new(f) {|b| # newの第1引数にウィジェットを指定すると # それが親ウィジェットとなる(fはフレーム) choices.each{|item| insert('end', item)} insert(0, "『右』クリックで次へ") self['selectbackground'] = 'pink' # selfは自分自身を指すキーワード b['background'] = '#e5d5d5' # つまりここではbと同じ値 yscrollbar(sbar) # 縦方向スクロールバーとして結合 pack("side"=>"right") bind('Button-3', proc { sels = b.curselection.collect {|i| b.get(i) }.join('と') text.value = "やっぱり"+sels+"ですよね〜\n"+text.value f.unpack; menu.pack("fill"=>"x"); text.pack}) bind('', proc { # 選択状態が変わる度呼ばれる howmanylabel['text'] = b.curselection.length.to_s+"個選択"}) } TkMessage.new(f) { pack("side"=>"left") text("リストボックスの選択方法(selectmode)を変更:") } TkButton.new(f, "text"=>"single") { command(proc {lb.selectmode("single")}) }.pack("fill"=>'x') TkButton.new(f, "text"=>"browse") { command(proc {lb.selectmode("browse")}) }.pack("fill"=>'x') TkButton.new(f, "text"=>"multiple") { command(proc {lb.selectmode("multiple")}) }.pack("fill"=>'x') TkButton.new(f, "text"=>"extended") { command(proc {lb.selectmode("extended")}) }.pack("fill"=>'x') } ###################################################################### # ラジオボタン radio_var = TkVariable.new radioframe = TkFrame.new {|fr| # frにはTkFrameオブジェクトが代入される # TkFrameはウィジェット群を格納できるウィジェット TkMessage.new(fr, "aspect"=>400, "font"=>fontM) { # aspectは縦横比(400%) text("これはラジオボタンです。複数候補から1つを選ばせます。\ これはボタン左端が揃ってるでしょ。 複数ボタンを縦に左端揃えで並べるときは、1個のボタンを pack('side'=>'left')で配置したフレームを順に pack('fill'=>'x')します。 (蕎麦の行を『右』クリックで次へ。)") }.pack("fill" => "x") TkFrame.new(fr) {|f| TkRadiobutton.new(f, "font"=>fontM) { variable(radio_var) value("カレー") text("カレーが一番") pack('side'=>'left') } }.pack("fill" => "x") TkFrame.new(fr) {|f| TkRadiobutton.new(f, "font"=>fontM) { variable(radio_var) value("ラーメン") text("ラーメンが一番") pack('side'=>'left') } }.pack("fill" => "x") TkFrame.new(fr) {|f| TkRadiobutton.new(f, "font"=>fontM) { variable radio_var value("蕎麦") select text("蕎麦が一番") bind('Button-3', proc { lblabel["text"] = radio_var.value+"ならどこで食べるのが一番?" fr.unpack; lbframe.pack}) pack('side'=>'left') } }.pack("fill" => "x") } ###################################################################### # チェックボタン cb_vars = Array.new cbframe = TkFrame.new {|fr| # ラベルとチェックボタンをグループ化 TkMessage.new(fr, "aspect"=>400, "font"=>fontM) { # aspectは縦横比(400%) text("これはチェックボタンです。左ボタンでON/OFF選ばせます。 で、あなたの気になることは?: (この説明文を真中ボタンクリックで次へ)") bind('Button-2', proc {cbframe.unpack; Tk.pack(radioframe)}) }.pack("fill" => "x") TkCheckButton.new(fr, "font"=>fontM) { text("夕飯") variable((cb_vars<fontM) { text("残額") variable((cb_vars<fontM) { text("このボタンの左端が揃ってないこと") variable((cb_vars< 58) { font(fontM) self.value="これはエントリ(入力窓)です。ここをクリックして入力開始。" bind('FocusIn', proc { self.value="これを消して名前を入力してReturnキーで次へ"}) bind('Return', proc { # 入力値をウィンドウタイトルに反映 Tk.root["title"] = self.value+"さんのウィンドウ" unpack cbframe.pack }) } ###################################################################### # ボタン button = TkButton.new({'text' => 'これはボタンです。クリックで次へ'}) { font(fontL) command(proc {unpack; entry.pack}) } ###################################################################### # ラベル TkLabel.new({'text' => ' これはラベルです。クリックで次へ '}) { bind('Button-1', proc {unpack; button.pack}) bind('Key-q', proc {exit}) # ラベルではキーは効かない font(fontL) }.pack # 全てのウィジェット共通のバインディングは Tk.root で。C-qで終了。 Tk.root.bind('Control-q', proc {exit}) Tk.root.bind('M1-q', proc {exit}) #lbframe.pack Tk.root["title"] = "Widgetデモ" Tk.mainloop