Create  Edit  Diff  Phillro Industries  Index  Search  Changes  History  Source  RSS  Note  wikifarm  Login

tut-tut_dialog

Author: NISHIO Mizuho

ダイアログ

各種ダイアログの紹介をします。

その1(メッセージダイアログ)

これから紹介するPhi::message_dlgはDelphiのMessageDlgにあたるメソッドです。スクリプトは下のようになります。

$(Apollo)/sample/tutorial/dialog1.rb

   1|require 'phi'
   2|require 'dialogs'
   3|
   4|def show_ok_msg(msg)
   5|  Phi::message_dlg(msg, Phi::MT_INFORMATION, [Phi::MB_OK], 0)
   6|end
   7|
   8|form = Phi::Form.new(:form1, 'フォームです')
   9|button = Phi::Button.new(form, :button1, 'hoge')
  10|button.align = Phi::AL_CLIENT
  11|
  12|button.on_click = proc do
  13|  result = Phi::message_dlg( 'メッセージダイアログです。',
  14|    Phi::MT_CONFIRMATION, [Phi::MB_OK, Phi::MB_YES, Phi::MB_NO,
  15|     Phi::MB_CANCEL], 0)
  16|  case result
  17|  when Phi::MR_OK
  18|    Phi::message_dlg('OKのボタンが押されました。', Phi::MT_INFORMATION,
  19|      [Phi::MB_OK], 0)
  20|    
  21|  when Phi::MR_YES
  22|    result2 = Phi::message_dlg('はいのボタンが押されました。',
  23|      Phi::MT_ERROR, [Phi::MB_ALL, Phi::MB_ABORT, Phi::MB_RETRY,
  24|      Phi::MB_IGNORE, Phi::MB_YES_TO_ALL, Phi::MB_NO_TO_ALL], 0)
  25|    case result2
  26|    when Phi::MR_ALL
  27|      show_ok_msg('すべてのボタンが押されました。')
  28|    when Phi::MR_ABORT
  29|      show_ok_msg('中止のボタンが押されました。')
  30|    when Phi::MR_RETRY
  31|      show_ok_msg('再試行のボタンが押されました。')
  32|    when Phi::MR_IGNORE
  33|      show_ok_msg('無視のボタンが押されました。')
  34|    when 9
  35|      #when Phi::MR_NO_TO_ALL
  36|      # Phi::MR_NO_TO_ALLはありません(result2には9が入ります)
  37|      show_ok_msg('すべていいえのボタンが押されました。')
  38|    when 10
  39|      #when Phi::MR_YES_TO_ALL
  40|      # Phi::MR_YES_TO_ALLはありません(result2には10が入ります)
  41|      show_ok_msg('すべてはいのボタンが押されました。')
  42|    end
  43|
  44|  when Phi::MR_NO
  45|    Phi::message_dlg('いいえのボタンが押されました。', Phi::MT_WARNING,
  46|      [Phi::MB_OK], 0)
  47|
  48|  when Phi::MR_CANCEL
  49|    Phi::message_dlg('キャンセルのボタンが押されました。',
  50|      Phi::MT_CUSTOM, [Phi::MB_OK], 0)
  51|  end
  52|end
  53|
  54|form.show
  55|Phi.mainloop

このスクリプトを実行すると、このような ウィンドウがあらわれます。

解説

このスクリプトはボタンが押されると、メッセージダイアログが表示され、表示されたダイアログのボタンを押すと、また別のダイアログが現れます。

2行目の require 'dialogs' はダイアログを扱う際に必要になるおまじないです。必ず require 'phi' の後に書くようにしてください。

4〜6行はRubyのメソッド定義です。内容については後で説明しますが、ここではdef show_ok_msg(msg) とすることで引数を一つとる show_ok_msg というメソッドを定義することができることを覚えておいてください。

8〜10行は起動時に表示されるフォームやボタンを生成しています。

12〜52行はボタンが押された時のアクションを定義しています。

13〜15行は今までなら1行で記述していた部分を3行に分けています。Rubyではパーサーが文法の区切りをある程度認識してくれますので、このように記述することが可能です。この部分では Phi::messge_dlg を呼び出してメッセージダイアログを表示させています。

Phi::message_dlg の引数は4つで、第1引数はメッセージダイアログに表示させる文字、第2引数はメッセージダイアログの種類を表す定数、第3引数はボタンを表す定数の組み合わせ( Array のオブジェクト)、第4引数はヘルプボタンがある時に表示するヘルプの番号になります。従って、13〜15行が実行されると、「メッセージダイアログです。」というメッセージが表示される4つのボタンを持つダイアログが現れます。

Phi::message_dlgの第2引数に取ることのできる値は下の5つです。定数にあわせて外見やタイトルバーに表示される文字が変化するので、サンプルスクリプトを実行して確認してみてください。

    • Phi::MT_CONFIRMATION(確認)
    • Phi::MT_CUSTOM(アプリケーション名)
    • Phi::MT_ERROR(エラー)
    • Phi::MT_INFORMATION(情報)
    • Phi::MT_WARNING(警告)

第3引数に下の定数を組み合わせたもの(Arrayのオブジェクト)を代入することでダイアログのボタンを変更することができます。例えば、「はい」と「いいえ」のボタンをダイアログに表示させたい場合は、 Phi::message_dlg の第3引数に [Phi::MB_YES, Phi::MB_NO] を代入します。

    • Phi::MB_ABORT(中止)
    • Phi::MB_ALL(すべて)
    • Phi::MB_CANCEL(キャンセル)
    • Phi::MR_HELP(ヘルプ)
    • Phi::MB_IGNORE(無視)
    • Phi::MB_NO(いいえ)
    • Phi::MB_NO_TO_ALL(すべていいえ)
    • Phi::MB_OK(OK)
    • Phi::MB_RETRY(再試行)
    • Phi::MB_YES(はい)
    • Phi::MB_YES_TO_ALL(すべてはい)

13行目では Phi::message_dlg の返り値がresultに代入されていますが、resultの値は押されたボタンによって値が変化します。13行目を例に取ると、「OK」のボタンが押されると Phi::MR_OK が、「はい」のボタンが押されると Phi::MR_YES が、「いいえ」のボタンが押されると Phi::MR_NO が、「キャンセル」のボタンが押されると Phi::MR_CANCEL が result に代入されます。ちなみに Rubyでは result は単なる変数なので、 Delphi と違って特殊な意味はありません。ボタンの定数 と Phi::message_dlg の返り値の関係は下のようになっています。

    • Phi::MB_ABORT -> Phi::MR_ABORT
    • Phi::MB_ALL -> Phi::MR_ALL
    • Phi::MB_CANCEL -> Phi::MR_CANCEL
    • Phi::MB_HELP -> 無し
    • Phi::MB_IGNORE -> Phi::MR_IGNORE
    • Phi::MB_NO -> Phi::MR_NO
    • Phi::MB_NO_TO_ALL -> 無し(整数の9)
    • Phi::MB_OK -> Phi::MR_OK
    • Phi::MB_RETRY -> Phi::MR_RETRY
    • Phi::MB_YES -> Phi::MR_YES
    • Phi::MB_YES_TO_ALL -> 無し(整数の10)

13行目以降のすべての場合について説明するのは無理なので、ここでは「はい」のボタンが押された時の動作について説明します。13行目の Phi::message_dlg で表示されたダイアログの「はい」のボタンを押すと、result には Phi::MR_YES が代入されます。16行目 case result はresultの値とその下に出てくる when 〜 の 〜 の部分を比較して一致した時(正確にはRubyの === や =~ の結果がtrueの時) に when の部分に書かれたことが実行されます。今回の場合は result の値が Phi::MR_YES ですので、二つ目の when Phi::MR_YES の部分(22〜42行)が実行されます。

22行では再びメッセージダイアログを表示させています。今回は6つのボタンが表示されるダイアログになっていますが、ここでは「すべてはい」のボタンが押されたことにして、説明を続けます。

「すべてはい」のボタンが押されると、result2には10(Phi::MR_YES_TO_ALLは定義されていません)が代入されます。次に25行目の case result2 の部分が評価されて39〜41行の部分が実行されますが、39と40行はコメントですので、実際に実行されるのは41行だけです。

41行は4〜6行で定義した show_ok_msg のメソッド呼び出しです。このメソッドを実行すると、メソッドの引数(「'すべてはいのボタンが押されました。'」)が4〜6行のmsgになり、5行目の Phi::message_dlg(msg, Phi::MT_INFORMATION, [Phi::MB_OK], 0) が実行されます。この場合は「'すべてはいのボタンが押されました。'」が表示される「OK」ボタンを一つ持つメッセージダイアログが表示されます。

メソッド定義で注意することは Ruby では Delphi の procedure や function が def (メソッド定義) ですべて統一されているということです( Delphi の property 等も def で定義することになります)。 Ruby のメソッドというのはすべて返り値を持ち、デフォルトでは nil が返ります。ですから本質的には Delphi の function にあたるものしか定義できないわけですが、上の show_ok_msg のように一見すると Delphi の procedure ように見えるメソッドを定義することもできます。Ruby のメソッドの返り値を設定したい場合は return を使うことになります(他の方法もあります)。

上のスクリプトはどのボタンを押すかによって分岐していくので、サンプルスクリプトを実行して色々と試してみてください。

補足: 残念ながら今のところDelphiのApllication.MessageBox?(Phi::APPLICATION.message_box)とShowMessage(Phi::show_message)は実装されていないようです。

クラスやメソッド

Phi

  • Phi::message_dlg

その2(ファイル選択のダイアログ)

$(Apollo)/sample/tutorial/dialog2.rb

   1|require 'phi'
   2|require 'dialogs'
   3|
   4|form = Phi::Form.new(:form1, 'formです')
   5|button = Phi::Button.new(form, :button1, 'hoge')
   6|button.align = Phi::AL_CLIENT
   7|
   8|button.on_click = proc do
   9|  dlg = Phi::OpenDialog.new
  10|  dlg.filter = 'テキスト(*.txt)|*.txt|すべて(*.*)|*|'
  11|  if dlg.execute
  12|    path = File::expand_path(dlg.file_name)
  13|    if FileTest::readable?(path)
  14|      File::foreach(path) do |l|
  15|        print l
  16|      end
  17|    else
  18|      Phi::message_dlg("#{path}: 読みこむことが出来ません。",
  19|      Phi::MT_ERROR, [Phi::MB_OK], 0)
  20|    end
  21|  end
  22|end
  23|
  24|form.show
  25|Phi.mainloop

このスクリプトを実行すると、このような ウィンドウがあらわれます。

解説

ボタンを押すと、ファイル選択のダイアログが表示されます。

目新しいのは8〜22行目ですので、今回はこの部分についてのみ説明します。

ボタンが押されると、9行目が実行されて Phi::OpenDialog? のオブジェクトが生成され、それがdlgに代入されます。 Phi::OpenDialog? はファイル選択ダイアログのクラスです。

次に10行目では dlg.filter( Phi::OpenDialog#filter )の属性によってファイル選択ダイアログに表示されるファイルの拡張子が設定されます。上の例では dlg.filter の値は 'テキスト(*.txt)|*.txt|すべて(*.*)|*|' です。 dlg.filter の説明は少々ややこしいですが、順を追って説明しようと思います。

最初に dlg.filter の文字を「|」で区切ると、

    • テキスト(*.txt)
    • *.txt
    • すべて(*.*)
    • *

のようになります。上の項目のうち奇数番目の項目がファイル選択ダイアログの「ファイルの種類」の項目に現れ、その次の偶数番目の項目が表示されるファイルの拡張子になります。従って、上の場合はファイル選択ダイアログの「ファイルの種類」には

    • テキスト(*.txt)
    • すべて(*.*)

の二つが表示されることになります。「ファイルの種類」で「テキスト(*.txt)」を選んだ場合、選択できるファイルは「*.txt」のワイルドカード(ファイルマスク?)で指定されるファイルになり、「すべて(*.*)」を選んだ場合は「*」で指定されるファイルを選択することが出来ます。ちなみに「*」ではすべてのファイルを選択することが可能です。

ファイル選択ダイアログには他にもいくつかのメソッド(プロパティ)があるので、試してみてください。

11行目のdlg.execute( Phi::OpenDialog#execute )で初めてファイル選択のダイアログが現れます。11行目以降はこのメソッドの返り値によって処理が変わります。 dlg.execute の返り値はファイル名が設定されている状態でダイアログの「開く」ボタンが押された時にtrueになり、「キャンセル」ボタンが押された時にfalseになります。

dlg.executeの返り値がtrueの時は12行目が実行されて、 path に選択されたファイルのフルパスが代入されます。 dlg.file_name( Phi::OpenDialog#file_name )の属性には選択されたファイルの名前が入っているので、それを Rubyの File::expand_path を使ってフルパスに変換し、path に代入しています。

13行目は path で表されるファイルが読みこみ可能かどうかを調べています。 FileTest?::readable? はRubyのFileTestモジュールに定義されたメソッドで、このメソッドによってファイルが読みこみ可能かどうかを調べることができます。このメソッドの返り値が false の場合は18〜19行が実行されて、「読みこむことが出来ません。」というメッセージが表示されます。逆に FileTest?::readable? が true を返した場合は14〜16行が実行されます。

14〜16行はファイルをオープンしてその内容を標準出力(apollo.exeの操作卓等)にプリントします。「File::foreach(path) do |l| 〜 end」ではpathのファイルの内容が1行読みこまれ、それが「l」に代入され、15行目で「l」が標準出力にプリントされます。「l」がプリントされると、pathのファイルの次の行が「l」に代入されて、再び15行目が実行されます。これがファイルの終わり(EOF)まで続きますので、最終的にpathのファイルの内容のすべてが標準出力にプリントされることになります。

14〜16行はRubyのイテレーターと呼ばれるもので、ループの抽象化等で使われる便利な仕組みです(馴れるまでは難しく感じるでしょうが)。RubyのFileクラスの使い方も含めて、詳しくはRubyのリファレンスマニュアルを参照してください。

クラスやメソッド

Rubyの組み込みモジュール

  • FileTest?

Rubyの組み込みクラス

  • File

Phi::OpenDialog?

その他

上で紹介したPhi::OpenDialogの他にも

のようなダイアログのクラスがあるので、試してみてください。

今回はダイアログを自分で定義しなかったですが、Rubyなら自分でダイアログを作ることも簡単にできます。後ほど紹介するつもりですので、頑張ってチュートリアルを読んでいってください。

Last modified:2004/11/26 10:56:42
Keyword(s):
References:[tut-tut_index]