トップページ | 2009年5月 »

2009年4月

2009年4月29日 (水)

ラーメンタイマーを作る2

とりあえず出来たタイマーだと3分の固定値しか計れません。最近のは1分とか5分とかバラバラだったりするので時間を変更できるように作り替えます。
ついでに、もっと見た目をわかりやすくするためにプログレスバーをつけて、時間が来たら音が鳴るようにしてみます。

続きを読む "ラーメンタイマーを作る2"

| | コメント (0) | トラックバック (0)

2009年4月26日 (日)

ラーメンタイマーを作る1

Hello Worldで概ね作り方が分かったので、なんか作ってみます。

いいアイデアが浮かばなかったので、3分カウントダウンをしてくれるカップラーメン用のタイマーを作ってみます。
画面は今まで作ったモノをいじって、時間を表示するWx:StaticTextとカウントを開始するきっかけとなるWx:Buttonがあればよいでしょう。

さて、時間をカウントするにはどうすればよいか。いつものwxRubyのリファレンスを見ていくとmiscellaneousのところにWx::Timerというズバリなものがあるじゃあないですか。コレは使えそうです。

説明を見てみると、

Secondly you may use the event handling mechanism to direct events to any object which inherits from EvtHandler. To do this use the longer constructor or set_owner. Then use the evt_timer method to connect it to the event handler which will receive TimerEvent notifications.

assuming ‘self’ is some Window or Wx::App timer = Wx::Timer.new(self) evt_timer(timer.id) { puts “Timer ticked” } timer.start(100)

evt_timerがイベントハンドラで、Wx:Timer.startとかstopで制御できるようです。引数でイベント生成の間隔が指定できると。あとは、通常のイベント処理と同じように書けば良さそうです。

画面を作って、コードを追加してみましょう。まずは画面から。

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  2. <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1">
  3.   <object class="wxFrame" name="MyFrame1" subclass="KT1">
  4.     <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
  5.     <size>500,300</size>
  6.     <title></title>
  7.     <object class="wxPanel" name="m_panel1">
  8.       <style>wxTAB_TRAVERSAL</style>
  9.       <object class="wxBoxSizer">
  10.         <orient>wxVERTICAL</orient>
  11.         <object class="sizeritem">
  12.           <option>1</option>
  13.           <flag>wxEXPAND</flag>
  14.           <border>5</border>
  15.           <object class="wxFlexGridSizer">
  16.             <rows>1</rows>
  17.             <cols>1</cols>
  18.             <vgap>0</vgap>
  19.             <hgap>0</hgap>
  20.             <growablecols>0</growablecols>
  21.             <growablerows>0</growablerows>
  22.             <object class="sizeritem">
  23.               <option>1</option>
  24.               <flag>wxALIGN_CENTER|wxALL</flag>
  25.               <border>5</border>
  26.               <object class="wxStaticText" name="m_staticText2">
  27.                 <font>
  28.                   <size>55</size>
  29.                   <family>default</family>
  30.                   <style>normal</style>
  31.                   <weight>normal</weight>
  32.                   <underlined>0</underlined>
  33.                 </font>
  34.                 <label>00:00</label>
  35.               </object>
  36.             </object>
  37.           </object>
  38.         </object>
  39.         <object class="sizeritem">
  40.           <option>0</option>
  41.           <flag>wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</flag>
  42.           <border>5</border>
  43.           <object class="wxButton" name="m_button1">
  44.             <label>START!</label>
  45.             <default>0</default>
  46.           </object>
  47.         </object>
  48.       </object>
  49.     </object>
  50.   </object>
  51. </resource>
  52.  

いつものようにXRCファイルを変換して

  1.  
  2. # This class was automatically generated from XRC source. It is not
  3. # recommended that this file is edited directly; instead, inherit from
  4. # this class and extend its behaviour there. 
  5. #
  6. # Source file: KT1.xrc
  7. # Generated at: Sun Apr 26 01:17:05 &#26481;&#20140; (&#27161;&#28310;&#26178;) 2009
  8.  
  9. class KT1 < Wx::Frame
  10.  
  11.   attr_reader :m_panel1, :m_statictext2, :m_button1
  12.  
  13.   def initialize(parent = nil)
  14.     super()
  15.     xml = Wx::XmlResource.get
  16.     xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
  17.     xml.init_all_handlers
  18.     xml.load("KT1.xrc")
  19.     xml.load_frame_subclass(self, parent, "MyFrame1")
  20.  
  21.     finder = lambda do | x |
  22.       int_id = Wx::xrcid(x)
  23.       begin
  24.         Wx::Window.find_window_by_id(int_id, self) || int_id
  25.       # Temporary hack to work around regression in 1.9.2; remove
  26.       # begin/rescue clause in later versions
  27.       rescue RuntimeError
  28.         int_id
  29.       end
  30.     end
  31.  
  32.     @m_panel1 = finder.call("m_panel1")
  33.     @m_statictext2 = finder.call("m_staticText2")
  34.     @m_button1 = finder.call("m_button1")
  35.     if self.class.method_defined? "on_init"
  36.       self.on_init()
  37.     end
  38.   end
  39. end
  40.  
  41.  

イベント処理のコードを追加。こんなかんじです。

  1. require 'rubygems'
  2. require 'wx'
  3. require 'KT1.rb'
  4.  
  5. class RamenTimer1 < KT1
  6.   def initialize(parent = nil)
  7.     super()
  8.  
  9.     # Button Event Handler
  10.     evt_button(m_button1.get_id()) {|event| on_buttonClick(event)}
  11.  
  12.     # Timer Event Handler
  13.     @time = 180
  14.     @m_timer = Wx::Timer.new(self)
  15.     evt_timer(@m_timer.get_id()) { |event| on_Timer(event)}
  16.   end
  17.  
  18.   # Button Event
  19.   def on_buttonClick(event)
  20.     @m_timer.start(1000)
  21.   end
  22.  
  23.   # Timer Event
  24.   def on_Timer(event)
  25.     time_str = "%02d" % (@time / 60).to_s + ":" + "%02d" % (@time % 60).to_s
  26.     m_statictext2.set_label(time_str)
  27.  
  28.     if(@time > 0)
  29.       @time = @time - 1
  30.     else
  31.       @m_timer.stop
  32.       @time = 180
  33.     end
  34.   end
  35.  
  36. end
  37.  
  38.  
  39. class App < Wx::App
  40.   def on_init
  41.     f =  ::RamenTimer1.new
  42.     f.show
  43.   end
  44. end
  45. App.new.main_loop
  46.  

実行してみましょう。

01

ちゃんと動いているようです。

| | コメント (0) | トラックバック (0)

2009年4月25日 (土)

Hello Worldをつくる3

ボタンを押してイベントを拾ってHello Worldの出力ができたので、今度は入力部分を扱ってみたいとおもいます。
入力フィールドを作って、ボタンを押すと出力用のフィールドに文字列が出るようにしてみます。

画面はこんな感じに作ってみました。

続きを読む "Hello Worldをつくる3"

| | コメント (0) | トラックバック (0)

Hello Worldをつくる2

やはり文字だけ表示されてもつまらないのでボタンを追加してみます。
ボタンを押したら文字が表示されるようにしてみましょう。

先ほどのプロジェクトを開いて、とりあえずFrameのsubclassをTest2に変えておきます。
次に、一番内側のSizerを選択してCommon-->xwButtonをクリック。プロパティのlabelを"Click here"と入力します。同じくwxALIGN_CENTER_HORIZONTALとwxEXPANDをチェックして細長いボタンを作製します。

01 02

wxStaticTextのプロパティlabelを値無しにセットします。続いて、ツールバーのExpandとStretchアイコンで面積を最大にします。この辺は好みです。最後にstyle-->wxALIGN_CENTREと、wxST_NO_AUTORESIZEをチェックしてテキストを中央寄せしておきましょう。

03

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  2. <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1">
  3.   <object class="wxFrame" name="MyFrame1" subclass="Test2">
  4.     <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
  5.     <size>500,300</size>
  6.     <title></title>
  7.     <object class="wxPanel" name="m_panel1">
  8.       <style>wxTAB_TRAVERSAL</style>
  9.       <object class="wxBoxSizer">
  10.         <orient>wxVERTICAL</orient>
  11.         <object class="sizeritem">
  12.           <option>1</option>
  13.           <flag>wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</flag>
  14.           <border>5</border>
  15.           <object class="wxStaticText" name="m_staticText2">
  16.             <style>wxALIGN_CENTRE|wxST_NO_AUTORESIZE</style>
  17.             <label></label>
  18.           </object>
  19.         </object>
  20.         <object class="sizeritem">
  21.           <option>0</option>
  22.           <flag>wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</flag>
  23.           <border>5</border>
  24.           <object class="wxButton" name="m_button1">
  25.             <label>Click here</label>
  26.             <default>0</default>
  27.           </object>
  28.         </object>
  29.       </object>
  30.     </object>
  31.   </object>
  32. </resource>
  33.  

これでXRCファイルを生成します。今度は多少オプションを変えます。

$ xrcise -o Test2.rb noname.xrc

今までは-aオプションを指定していたので、Wx:Appのクラスまでコードが生成されていましたが、コレが無くなったのでFrameクラス部分のコードだけが生成されるようになりました。

今後、今回のように後からボタン追加やその他画面の変更があるかもしれないので、自動生成されるコードを直接いじるのではなく、このクラスを継承して、必要な処理を追加していくやり方にします。後からの変更が合った場合の影響範囲が少なくなって作りやすくなります。

ということで、新しく別ファイルを開いてrubyのコードを書いていきます。とりあえず新しく作った画面を表示するだけのソースコードを書いてみます。

  1. require 'rubygems'
  2. require 'wx'
  3. require 'Test2.rb'
  4.  
  5. class Hello_World2 < Test2
  6.   def initialize(parent = nil)
  7.     super()
  8.   end
  9. end
  10.  
  11.  
  12. class App < Wx::App
  13.   def on_init
  14.     f =  ::Hello_World2.new
  15.     f.show
  16.   end
  17. end
  18. App.new.main_loop
  19.  

Hello_World2.rb でセーブしました。これを実行すると、下部にボタンだけがある画面が表示されるようになったはずです。

では次に、ボタンが押されたときの処理を追加してみます。ボタンクリック時のイベントハンドラを記述すると、クリックしたときの反応を定義できます。

wxRuby Documentation: Class ReferenceでWx:ButtonのEvent handler項目を見てみるとevt_button(id) { | event | ... }と書いてあります。実際どのような感じで書けばよいのかさらに調べてみるとwxRubyのTutorialにサンプルが載っていました。これを今作った環境に合わせて書き換えてみます。

今回追加したボタンのattr_readerはm_button1なのでコレに置き換えて
押された場合はon_buttonClickを呼んで、そこで処理させることにします。処理の中身はwxStaticTextのlabelにHello Worldをセットすることです。これもリファレンスのwxStaticText項目を見るとset_label()を使用すると文字をセットできそうです。
なので、このように書いてみました。

  1. require 'rubygems'
  2. require 'wx'
  3. require 'Test2.rb'
  4.  
  5. class Hello_World2 < Test2
  6.   def initialize(parent = nil)
  7.     super()
  8.     evt_button(m_button1.get_id()) {|event| on_buttonClick(event)}
  9.   end
  10.  
  11.   def on_buttonClick(event)
  12.     m_statictext2.set_label('Hello World')
  13.   end
  14. end
  15.  
  16.  
  17. class App < Wx::App
  18.   def on_init
  19.     f =  ::Hello_World2.new
  20.     f.show
  21.   end
  22. end
  23. App.new.main_loop

では、実行してみましょう。

$ ruby Hello_World2.rb

04

このように表示されました。

 

| | コメント (2) | トラックバック (0)

2009年4月19日 (日)

Hello Worldをつくる1

定番のHello Worldをつくってみます。

wxFormBuilderを起動してwxFormBuilderの使い方で説明した設定をします。これだけだと味気ないので、今度はパネルを追加して文字を表示させてみます。

まずはPanelの追加。その前にレイアウトを決めるSizerというモノを追加しなければ行けません。いきなりPanelを追加しようとしてもできません。ということでLayout-->wxBoxSizerを追加。

01_2

左側のツリーにSizerのアイコンが追加されてFrameの内側が赤線で光っている状態になりました。これでSizerを追加できました。続いてContains-->wxPanelを追加。

02

パネルが表示されました。ココに文字を貼り付けるには、wxStaticTextを追加します。だけどその前にレイアウトを決めないといけないので、パネルの上に同じくSizerを追加します。手順は同じです。そして、タブよりCommon-->wxStaticTextをクリック。右側のプロパティでlabelの値をHello Worldと入力します。ついでに中央に表示させてみます。同じくプロパティよりflag-->wxALIGN_CENTER_HORIZONTALをチェックしておきます。

04

05

これで完成です。XRCファイルを出力しましょう。ファイルの中身はこんな感じです。

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  2. <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1">
  3.   <object class="wxFrame" name="MyFrame1" subclass="Test1">
  4.     <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
  5.     <size>500,300</size>
  6.     <title></title>
  7.     <object class="wxPanel" name="m_panel1">
  8.       <style>wxTAB_TRAVERSAL</style>
  9.       <object class="wxBoxSizer">
  10.         <orient>wxVERTICAL</orient>
  11.         <object class="sizeritem">
  12.           <option>0</option>
  13.           <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
  14.           <border>5</border>
  15.           <object class="wxStaticText" name="m_staticText2">
  16.             <label>Hello World</label>
  17.           </object>
  18.         </object>
  19.       </object>
  20.     </object>
  21.   </object>
  22. </resource>
  23.  

これをxrciseでコンバートします。

$ xrcise -a App1 -o HelloWorld1.rbw noname.xrc

rubyのソースコードがこんな感じに変換されます。rubygemsの追加を忘れずに。

  1.  
  2. require 'rubygems'
  3. require 'wx'
  4.  
  5. # This class was automatically generated from XRC source. It is not
  6. # recommended that this file is edited directly; instead, inherit from
  7. # this class and extend its behaviour there. 
  8. #
  9. # Source file: noname.xrc
  10. # Generated at: Sun Apr 19 11:52:55 &#26481;&#20140; (&#27161;&#28310;&#26178;) 2009
  11.  
  12. class Test1 < Wx::Frame
  13.  
  14.   attr_reader :m_panel1, :m_statictext2
  15.  
  16.   def initialize(parent = nil)
  17.     super()
  18.     xml = Wx::XmlResource.get
  19.     xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
  20.     xml.init_all_handlers
  21.     xml.load("noname.xrc")
  22.     xml.load_frame_subclass(self, parent, "MyFrame1")
  23.  
  24.     finder = lambda do | x |
  25.       int_id = Wx::xrcid(x)
  26.       begin
  27.         Wx::Window.find_window_by_id(int_id, self) || int_id
  28.       # Temporary hack to work around regression in 1.9.2; remove
  29.       # begin/rescue clause in later versions
  30.       rescue RuntimeError
  31.         int_id
  32.       end
  33.     end
  34.  
  35.     @m_panel1 = finder.call("m_panel1")
  36.     @m_statictext2 = finder.call("m_staticText2")
  37.     if self.class.method_defined? "on_init"
  38.       self.on_init()
  39.     end
  40.   end
  41. end
  42.  
  43.  
  44. class App1 < Wx::App
  45.   def on_init
  46.     f =  ::Test1.new
  47.     f.show
  48.   end
  49. end
  50. App1.new.main_loop
  51.  
  52.  

では実行してみましょう。こんなかんじで画面が表示されればOKです。

06

| | コメント (0) | トラックバック (0)

2009年4月18日 (土)

wxRuby関連リンク

wxRubyで始めるGUIプログラミング
インストールからサンプルアプリの作り方まで網羅していています。各種GUI部品一覧が使う上でイメージしやすく参考になります。

wxRuby Documentation: Class Reference
クラスリファレンスです。やりたいことができそうな機能や必要な引数をここで確認してます。

wxPython Index
違う言語ですが作製する上で参考になります。
リンク切れになってます。どこかに移行したのでしょうか。参考にしていたので非常に残念です。2010/10

wxWidgets (wxWindows) 日本語ドキュメントプロジェクト
英語ドキュメントでよく分からない場合は、こちらを。運がよければ訳されているかも。活動自体は停滞している模様。

wxRubyAPIドキュメント和訳
こちらはwxrubyの英語ドキュメントを訳しているGJなブログ。まだ量自体は少ないので今後に期待。

 

| | コメント (0) | トラックバック (0)

wxFormBuilderの使い方

wxFormBuilderを起動して最初の画面がコレ。作った内容はプロジェクトという単位で管理していきます。右のプロパティでwxRubyのための設定をします。

01_3

wxRubyで必要な形式はXRCなのでその設定をします。右のプロパティでXRCにチェックを入れます。とりあえずはこれでOK。次に画面を作ります。

02_2

Formタブをクリックすると下にアイコンが出てきます。一番左のFrameをクリック。

03_4

ウィンドウが出てきました。コレにパネルやらボタンやらを配置して画面を作っていきます。今回はこれ以上追加せず、テストとしてこの画面のみ表示させてみます。

04

次にFrameの設定で必要な値をセットします。右のプロパティでsubclassのnameを設定します。ここではTest1という名前にしてみました。わかりやすい名前を付けましょう。

07

ココまでで準備OKです。FileよりSaveをしておきましょう。次にXRCコードの出力です。出力する前に実際の画面をプレビューできるので見ておきます。メニューのViewよりXRC Windowをクリックしましょう。

08

今画面で表示されているものと同じようなウィンドウが出てきたはずです。より実行時のイメージに近い表示となっているはずです。

09

確認できたらXRCファイルを生成します。FileよりGenerate Codeをクリックします。先ほどセーブしたプロジェクトファイルと同じ場所にnoname.xrcというファイルができているはずです。これが今エディットした画面のXRCファイルです。

10

画面の設計が終わったので、このXRCファイルを元にrubyのソースコードを作製します。コンバートしてくれるスクリプトがあるので、それにXRCファイルを引数として渡して実行します。下記が実行例です。

$ xrcise -a App1 -o App1.rbw noname.xrc

ファイルの中身はこんな感じです。gemでインストールしたので生成したファイルにrubygemsを加えています。

  1. require 'rubygems'
  2. require 'wx'
  3.  
  4. # This class was automatically generated from XRC source. It is not
  5. # recommended that this file is edited directly; instead, inherit from
  6. # this class and extend its behaviour there. 
  7. #
  8. # Source file: noname.xrc
  9. # Generated at: Sat Apr 18 02:04:25 &#26481;&#20140; (&#27161;&#28310;&#26178;) 2009
  10.  
  11. class Test1 < Wx::Frame
  12.  
  13.   def initialize(parent = nil)
  14.     super()
  15.     xml = Wx::XmlResource.get
  16.     xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
  17.     xml.init_all_handlers
  18.     xml.load("noname.xrc")
  19.     xml.load_frame_subclass(self, parent, "MyFrame1")
  20.  
  21.     finder = lambda do | x |
  22.       int_id = Wx::xrcid(x)
  23.       begin
  24.         Wx::Window.find_window_by_id(int_id, self) || int_id
  25.         # Temporary hack to work around regression in 1.9.2; remove
  26.         # begin/rescue clause in later versions
  27.       rescue RuntimeError
  28.         int_id
  29.       end
  30.     end
  31.  
  32.     if self.class.method_defined? "on_init"
  33.       self.on_init()
  34.     end
  35.   end
  36. end
  37.  
  38.  
  39. class App1 < Wx::App
  40.   def on_init
  41.     f =  ::Test1.new
  42.     f.show
  43.   end
  44. end
  45. App1.new.main_loop

では実行してみましょう。

$ ruby App1.rbw

こんな感じでウィンドウが表示されればOKです。ちょいと面倒な部分もありますが一回設定しておけばよいだけなのでそれほど手間ではないでしょう。

11

| | コメント (0) | トラックバック (0)

2009年4月12日 (日)

まずは準備

まずは作業する環境です。私の場合は、Windows 2000 上で開発してます。wxRubyでGUIアプリを作るには以下が必要です。

  • Ruby
  • wxWidgets
  • wxRuby

Rubyは勿論必須ですね。私の環境ではUNIXライクな環境でやりたかったのでMigGWとMSYSをいれてmingw32版Rubyをインストールしています。mingw32版は多分このあたりからもってきたやつをつかっています。使用しているバージョンは1.8.4です。

wxWidgetsはここからwxMSWをダウンロードしてインストーラを実行すればよかったはず。LinuxはwxWidgetsのインストールが必要ですがWindowsはgemに含まれています。

Linuxはパッケージ導入できなければコンパイルが必要っぽいです。その他、SWIGというのが必要みたいです(Linuxで試してないので分かりません。ココにやり方が載ってました。)。

wxRubyはRubyをインストールした後、gemでインストールすればOK。

# gem install wxruby --remote

ruby1.9.xの場合は、

# gem install wxruby-ruby19 --remote

でインストールされるんじゃあなかろうか。試してないので分からないですが多分OKでしょう。OKだった。

一応コレで動くモノを作れると思うのですが、開発がラクになるようサポートしてくれるツールも入れときます。

  • wxFormBuilder
  • wxSugar

wxSugarはgemでインストールできます。

# gem install wx_sugar --remote

wxFormBuilderはココからダウンロードして使います。これは一言でいうと画面設計ツールです。設計したフォームなどの設定はXRCファイルとして保存されます。XRCというのはXML Resourceの略でwxWidgets用のuser interface markup languageだそうです。もっと詳しく知りたい方はこちらをどうぞ。XRCファイルをwxSugarの中にあるxrciseで処理すると即実行可能なRubyのソースを作ってくれます。

とりあえず以上で準備完了です。今後ここでGUIアプリを作る基本的な流れは、

  • wxFormBuilderで画面を設計
  • xrciseで雛型作製
  • 雛型を元に必要な処理を加えていく。
  • テスト、実行してみる。

になります。さっそくGUIアプリを作りたいのですが、その前にちょっとだけwxFormBuilderの使い方を説明します。

| | コメント (0) | トラックバック (0)

2009年4月10日 (金)

はじめに

RubyでGUIを使ったアプリをつくる際に利用するwxRubyのことを書いていきます。

日曜プログラマでRubyはいろいろと勉強中なので、更新が遅かったりコードがヘンだったりすると思いますが、とりあえず動けばよいをモットーにやっていくのでヨロシクです。

| | コメント (0) | トラックバック (0)

トップページ | 2009年5月 »