Rubyを使いWindowsでもLinuxでも動くGUIアプリケーションを作ってみたい。作るアプリケーションは、引数としてプログラムパスを受け取り、一定時間経過後そのプログラムを実行するというシンプルなものにする。起動したらダイアログを表示し、カウントダウンタイマ付のボタンを用意する。ボタンは「はい」と「いいえ」とし、引数でタイムアウト時のデフォルト処理をしていする。タイムアウトすればデフォルトの処理が動き、ユーザがボタンをクリックすれば、希望の動作を行うようにする。GUIライブラリはtkを使う。
WindowsにRubyをインストール
ここからruby-1.9.1-p0-i386-mswin32.zipをダウンロード、C:\Ruby\に展開した。libフォルダのなかにtkがあるのでtkをインストール必要はないのだろう。
簡単なGUIプログラムが動くかテストしてみる。ここを参考に以下のようなファイルHello.rbを作る。
1 2 3 4 5 6 7 8 9 10 |
#!/usr/bin/env ruby require 'tk' TkLabel.new { text "Hello, World!" pack } Tk.mainloop |
コマンドプロンプトを開き、実行してみるとまずいかのようなメッセージボックスがでた。
---------------------------
ruby.exe - DLL が見つかりません
---------------------------
ダイナミック リンク ライブラリ tk84.dll が指定されたパス c:\Ruby\bin;.;C:\WINNT\system32;C:\WINNT\system;C:\WINNT;C:\WINNT\system32
に見つかりませんでした。
---------------------------
OK
---------------------------
コマンドの出力は以下のようなものだった。
C:\Work\Ruby>c:\ruby\bin\ruby hello.rb
c:/ruby/lib/ruby/1.9.1/tk.rb:6:inrequire': 126: 指定されたモジュールが見つかり
ません。 - c:/ruby/lib/ruby/1.9.1/i386-mswin32/tcltklib.so (LoadError)
from c:/ruby/lib/ruby/1.9.1/tk.rb:6:in'
from hello.rb:3:inrequire'
from hello.rb:3:in' C:\Work\Ruby>
126というのはおそらくGetLastError()の戻り値だろう、そしてtcltklib.soは存在するので、これをLoadLibrary()したとき依存するtk84.dllが読めないということ?
tk.rbはあくまでtkを使うためのラッパーであってtkそのものはインストールしなければならないということだと思うのでここへ行ってActiveTCLをダウンロードする。といってもエラーはtk84.dllで出たので同じバージョンをダウンロードしよう。「Other System and Version」をクリックしてActiveTcl8.4.9.1.139183-win32-ix86.exeをインストールした。リブートご再び実行すると、以下のように起動できた。
これで作り始める準備が整った。ここで作るのは最初に書いたように以下のようなイメージのアプリだ。
1 2 3 4 5 |
-------------------------------------- C:\aaa\bbb.exeを起動します。 [OK (のこり10秒)] [Cancel] -------------------------------------- |
ところがここで問題が。Rubyスクリプトファイルをいくら書き換えても、最初に実験したHello.rbの内容が表示される。以下のような1行だけのファイルでも実行される。
1 |
require 'tk' |
Rubyのことはまだよくわかっていないが、これは何かのバグだろうか?どっかにキャッシュが残っているのだろうか?ググってもよくわからない。仕方ないのでいったんActiveTCLをアンインストールしもっと古いヴァージョンを使ってみる。
ActiveTcl8.4.17.0.283511-win32-ix86-threaded.exeをダウンロード、インストールし、リブートした結果、以下のように正常に動くようになった。
よくみるとWindowsの場合と違ってクライアントエリアにもHello World!の表示がある。Windowsの方はインストールに失敗があったのだろうか?
よってWindowsはここで止めてFedora10に移る。rubyはインストールしてあるので以下のようにtkをインストールした。
# yum install ruby-tcltk
あとは頑張って以下のプログラムを書いてみた。多分いい加減なところがいっぱいあるだろうが。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
require 'tk' if ( ARGV.length < 1 ) print "Usage : rubytk.rb program\n" exit end label = "10秒後に" + ARGV[0] + "を起動します" def launch system(ARGV[0]) exit end $tkl = TkLabel.new(nil, 'text'=>label) $tkl.pack $tkb = TkButton.new(nil, 'text'=>'起動', 'command'=>proc{launch}) $tkb.pack('side'=>'right') TkButton.new(nil, 'text'=>'止める', 'command'=>proc{exit}).pack('side'=>'right') $count = 10; def timer() Tk.after(1000, proc { $count = $count - 1 c = "起動 (%d)" % $count $tkb.text = c if $count < 0 launch end timer() # repeat timer }) end timer() Tk.mainloop |
アプリの起動にはsystemメソッドを使っているが、これを使うと起動したアプリが終了するまで戻ってこなくなる。が、まぁいいや。以下のように実行できた。
$ ruby rubytk.rb gedit
C:\T>c:\ruby\bin\ruby.exe -Ku rubytk.rb notepad