2007年11月20日

ruby/tk placeで指定できる値

エントリTkXXXXXのwidth,heightでTkButtonやらでwidth,heightがピクセル指定できなくてまいったと言う話を書いたが、
placeで指定すると正しくピクセル単位で解釈してくれるらしい。素晴らしい
と言うわけでplaceで指定できるものを調査。
#ruby/tk ver.0.9.3
require "tk"
$KCODE="EUC"

#400*400のborder幅1のrootを作成
Tk.root.width(400)
Tk.root.height(400)
Tk.root.borderwidth="1"
Tk.root.relief="groove"

#※※このプログラムの説明は100%保障されていません※※
#■■placeによるウィジットの配置

#■x , y 位置の絶対値表示
#■relx , rely 位置の相対表示(親の幅を基準に0.0〜1.0)
TkButton.new{
	text "位置絶対値指定"
	place(:x=>100, :y=>100)
}
TkButton.new{
	text "位置相対値指定"
	place(:relx=>0.4, :rely=>0.4)
	#0.4*400=160 (但しbordermodeを考慮していない場合)
	#実質デフォルトのbordermodeはinsideなので、この場合
	#0.4*(400-2)≒159
	#bordermodeの詳細は下を参照
}

#■width , height 幅、高さの絶対値定義
#■relwidth , relheight 幅、高さの相対値定義
TkButton.new{
	text "幅高さ絶対値"
	place(:x=>200, :y=>10, :width=>100, :height=>30)
}
TkButton.new{
	text "幅高さ相対値"
	place(:x=>200, :y=>40, :relwidth=>0.2, :relheight=>0.2)
}


#■anchor => [where] ウィジットを配置したい位置
#デフォルト値 nw
#指定可能値   n,ne,e,se,s,sw,w,center
#n:北 e:東 w:西 s:南 の意味
TkButton.new{
	text "左上(北西)基準"
	place(:x=>250, :y=>250)
}

TkButton.new{
	text "右下(南東)基準"
	place(:x=>250, :y=>250, :anchor=>'se')
}

#■bordermode => [mode] 親の内側の線を除くか除かないか
#デフォルト値 inside  #Tk.root.borderwidthの内側から表示
#指定可能値   outside #Tk.root.borderwidthの幅に関係なく端から表示
TkButton.new{
	text "inside"
	place(:x=>0, :y=>0)
}
TkButton.new{
	text "outside"
	place(:x=>0, :y=>24, :bordermode=>'outside')
}

#■in => [master] マスタを直接指定
frame = TkFrame.new{
	borderwidth=3
	relief="groove"
	place(:x=>0,:y=>200,:width=>50,:height=>50)
	#実用性無い気がするけどこんな事もできる
	TkButton.new{
		text "outFrame"
		place(:x=>0, :y=>100,:in=>Tk.root)
	}
}

TkButton.new{
	text "intoFrame"
	place(:x=>0, :y=>0,:in=>frame)
}

Tk.mainloop
画面イメージはこちら
placeImg 色々入り組んでるので非常に判り辛いが、全てのオプションを網羅しているはず。
詳しくは自分でやって下さい。
ポイントとしては画面の幅を広げた時にrelが頭についてるのは位置、または幅高さが変わる。
相対表示ですからね。以上がplaceのoptionの使い方。

2007年11月17日

win32APIの使用方法

rubyは多様なプラットフォームで使用できることが売りですが、windowsを使用しているのでwin32APIを使い方を知りたくなった。
rubyリファレンス:win32API http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Win32API
rubyでwin32APIを使う資料は沢山あるが、詳しく調べるまで内部がどんな感じかイマイチよくわからなかったので、コメントをねちっこくつけたサンプルを作ってみた
require 'Win32API'

class Win32API
  def Win32API.MessageBox(wnd, text, caption, type)
    #Win32API.newは左からdllname, proc, import, export
    #dllname : procの関数があるdllの名称。で、user32.dllってどこにあるの?C:検索しても出てこなかったんだけど
    #proc    : 関数名今回の場合MessageBox。で、MessageBoxを検索かけてみると、
    #            int MessageBox(HWND   hWnd,PCTSTR pszText,PCTSTR pszCaption,UINT   uType)
    #            と言った感じで、四つの引数を持ち、int型で返しているのが判る。そこで次の項目
    #import  : 引数として適用する型を指定する。これが結局上記の4引数になる。
    #            "p" ポインタ 
    #            "n", "l" long *1 
    #            "i" int 
    #            "v" void 
    #          から、最初三つはポインタとして(名称の頭のアドレス?),最後の一つは数値として扱っているのが分かる。
    #         これがcall時の引数として渡される事になる
    #export  : 戻り値。指定した型で戻ってくる。iなので、int型で返ってくる
    messagebox = Win32API.new('user32', 'MessageBox', %w(p p p i), 'i')

    messagebox.call(wnd, text, caption, type) #左からp p p i
  end
end

p Win32API.MessageBox(0, "てすと", "テスト",0)
win32API MessageBox参考 http://yokohama.cool.ne.jp/chokuto/urawaza/api/MessageBox.html
とにかく簡単な事を簡潔にこなしていこう。

2007年11月14日

TkXXXXXのwidth,height

TkLabelやTkButtonのwidthとheightの指定がどう見てもピクセル単位で無い。
# ruby/tk ver.0.9.3
require "tk"

sampleBtn = TkButton.new {
	text '拡大'
	width 15
	height 15
	command{
		#width,heightそれぞれ+5
		sampleBtn.width  += 5 
		sampleBtn.height += 5
		puts sampleBtn.width.to_s + "x" + sampleBtn.height.to_s
	}
	pack
}

Tk.mainloop
ボタンを押下するたびにボタンのwidth,heightを+5する処理。
実際に動作させてみるとわかるが、明らかにピクセル単位で大きくならない
しかもwidthとheightで広がる幅が明らかに違う(Windows XP SP2調べ)
調査してみた所
widthが約6px
heightが約13px
の幅で広がっていくようだ。実際に画面レイアウトを考える時は注意しようかな。
ちなみにrootやTkFrameのwidth,heightの幅はピクセル単位。うーむ。

2007年11月12日

Symbolクラスが良くわからなかった

rubyのサンプルソースを見ているとよく
:hogehoge
のような物が使われていた。よく判らなかったので調べて見た所、どうもSymbolオブジェクトのようです。

参考:Rubyリファレンスマニュアル
http://www2.ruby-lang.org/ja/man/?cmd=view;name=Symbol
使い方としては文字の定義を明確にする時によく使うそうです。よくわかりませんね。
#■ :[名称] はシンボルのオブジェクトらしい
data = :hoge #は正しく代入できる。当然だけど

#Symbolは任意の文字列と一対一に対応するオブジェクトなので
p :hoge.id == :hoge.id
#はtrueを返す。
#一方String
p "hoge".id == "hoge".id
#は一対一に対応していないのでfalseを返す

#シンボルは文字の定義を明確にしたい時に使用するそうです。
#例えばhashのキー項目
hashData = {:key1 => "data1" , :key2 => "data2"}
puts hashData[:key1]
puts hashData["key1"] #もちろんこれはnil
puts hashData["key1".intern] #internメソッドで String -> Symbolに変換。逆の変換はto_s(:key1.to_s)

#ここから今回調べてる途中に知ったから一応メモ
puts :hoge.class
#これでクラス名が返ってくる。何かには使えるかも。これを使って何クラスかによって処理を分岐とか作ろうかな。
#そう思っていた時期が俺にもありました。
#kind_of?([クラス名]) ->  オブジェクトが、任意のクラスまたはそのサブクラスのインスタンスかどうか
#と言うステキなメソッドがあった
puts :hoge.kind_of?(Symbol) ? "シンボルクラスっす" : "シンボルクラスじゃないっす"
Stringのデータは1度作成するたびにデータを生成する(だからidが変わる)
一方Symbolは実行開始時に全てのデータを一度生成する。(だからidが変わらない)
なので、Symbolで書いた方が速度が上がるらしいです。
ちなみにputs Symbol.all_symbolsで全てのシンボルが見れます

可読性が上がるとか書いてあったが、実際上がってるのかイマイチ理解できない。
でも多分hashを読み込む時とかに
hashData["key"]
って書くより、
hashData[:key]
って書いた方が何かプログラムっぽいから好きだって人が多いに違いない。そうだ、きっとそうだ。こうしてまた一つ解決した気になった。
うん、でもこんなの初めてでたら迷うよね。

2007年11月11日

Ruby/Tk rootの処理色々

Ruby/Tkを使用してGUIのソフトウェアを作ろうと思ったので、まずはメインとなるroot周りをどう使えば良いか調べた。
基本はVBやC#でよく触りそうな辺りが触れるかの簡単な調査
# ruby/tk ver.0.9.3
require "tk"

#ウィンドウタイトルの定義
Tk.root.title("ほげほげ")
#ウィンドウサイズ変更の禁止
Tk.root.resizable(0, 0)
#背景色の変更 -> rootに背景色の設定は無い?
Tk.root.bg = 'white'
#Tk.root.bg = '#DDFFDD'	#色コードで

#■画面表示ウィンドウ関連
#画面サイズの取得
screenX = Tk.root.winfo_screenwidth  # Tk.root.winfo_vrootwidthでも可
screenY = Tk.root.winfo_screenheight # Tk.root.winfo_vrootheightでも可

#ウィンドウ位置を取得
windowX = Tk.root.winfo_x
windowY = Tk.root.winfo_y

#ウィンドウサイズ+位置の決定(ウィンドウサイズ800*600で0,0の位置に表示)
Tk.root.geometry = "800x600+0+0"

#ウィンドウサイズのみ設定
#Tk.root.width(800)
#Tk.root.height(600)
#+以降のみを入力すると位置の移動のみ(widthやheightのような他のメソッドがありそう)
#Tk.root.geometry = "+100+100"

#上記から、画面中央表示
windowWidth  = 800
windowHeight = 600
windowLeft = ((screenX / 2).to_i - (windowWidth / 2).to_i)
windowTop  = ((screenY / 2).to_i - (windowHeight / 2).to_i)
Tk.root.geometry(windowWidth.to_s + "x" + windowHeight.to_s + 
"+" + windowLeft.to_s + "+" + windowTop.to_s )

#■使う人は使うであろう処理
#overrideredirectはウィンドウ描画中には効果が無いので、再表示する。
#ウィンドウのフレーム除去(true:フレーム除去 false:フレーム付加)
#Tk.root.overrideredirect(false)
#ウィンドウを消す
#Tk.root.withdraw
#ウィンドウを表示
#Tk.root.deiconify
#画面を最前面に出す
#Tk.root.attributes('topmost', 1)

#Buttonも試しにつけてみる
TkButton.new {
	text "Button"
	command {
		#overrideredirectの使用例。更に応用して擬似フルスクリーンとかに使用
		Tk.root.overrideredirect(!Tk.root.overrideredirect).withdraw.deiconify
	}
}.place('x' => 400, 'y' => 200)

Tk.mainloop
800*600の白い画面が中央に表示されるサンプル。
ちょこんと置かれているボタンを押すとウィンドウのフレームを除去する。もう一度クリックするとフレームが戻る

2007年11月08日

配列の内容を調べる

今は簡単な事でもやって驚く時期なのです。
配列内にデータが存在するかのチェックを簡単にする関数が無いか探した所やっぱりありました。ruby素敵。
# rubyは配列内のデータを全て同じ型にする必要は無い
dataList = ["1" , [1] , [1,2] ]

searchData1 = [1,2] # 配列単位で検索対象にできる
searchData2 = 1     # ≠[1]

# [配列].index([検索対象]) -> 配列の中に検索対象のデータが存在した場合に対象の位置を取り出す
# 対象が存在しない場合はnilを返す
#puts dataList.index(searchData) #=> return 2
#puts dataList.index(searchData2) #=> return nil
#配列内の配列をチェックする事は可能
if !(dataList.index(searchData1).nil?)
  puts "Data1:一致"
else
  puts "Data1:不一致"
end

#配列内の配列の中の数値とは一致しない
if !(dataList.index(searchData2).nil?)
  puts "Data2:一致"
else
  puts "Data2:不一致"
end

#複数のデータを一気に判定する [[1,2] , 1 , "1"]
searchList = [searchData1 , searchData2 , "1"]
# [配列] & [配列] 積集合
resultList = dataList & searchList #=> return ["1",[1,2]]
#resultList = searchList & dataList だと配列の並び順が変わる #=> return [[1,2] , "1"]
if (resultList != [])
  puts "一致データ:"
  p resultList.to_a  
else
  puts "一件も一致していません"
end
単一のデータを検索する時はindex、複数のデータを検索する時は積集合の結果を調査すれば見た目単純で綺麗。
配列の内容が大量になった場合の処理速度とかは気になる所ですが(特に積集合)、簡単に配列の中身をデータ型(rubyなのでクラスの判別になるのでしょうか)まで判別できるので便利。な気がする。
でも型が違うデータの配列なんて作る事はあるのだろうか。。。

あと開発練習にRDEを使用していたが、最初エディタの日本語が文字化けしていた。
結局[ツール]→[エディタ設定]→[フォント]でフォントを日本語フォントに設定するだけでした。気づけよ

[クラス].methods

小さい事からコツコツと覚えた事を少しずつメモします。よろしくお願いします。
クラス内のメソッドを全て表示する。
require 'mechanize'
# WWW内のメソッドを全て表示
puts "■WWW"
WWW.methods.to_a.each { |method|
	puts method
}
puts
# WWW:Mechanize内のメソッドを全て表示
puts "■WWW::Mechanize"
WWW::Mechanize.methods.to_a.each { |method|
	puts method
}
メソッドの名前が分からない、ネットで検索しても見当がつかないと言う時に
一覧出して名前から機能を想像する時に使える。気がする(弱気)

Archives
  • ライブドアブログ