2011年2月24日木曜日

wxPythonでpingのGUIを作ろう

今回はwxGlade及びwxPythonを使ったリハビリ作の第一弾です。
既存のpingコマンドにGUIのインタフェースを付けてしまおうです。

環境設定は前回までで完了しているということで進めます。
参考(ま、お好みでどうぞ)

順を追って説明して行きましょう


  1. まず何よりも、どんなアプリを作りたいのか見た目やプロトタイプを作りましょう。
    実際のところ、どうやってこの工程を進めるかというのは慣れや感性によると思います。wxGladeで作りやすいかどうかということもあります。慣れてくると何となくサクッと決められるようになるはずです。
    今回はとりあえず以下のようなものを作ることにいたしましょう。
  2. 実際に作り始める前に、プロジェクトを作成します。Eclipseを開き、「File」→「New」→「Project」(あるいは、プロジェクト新規作成ボタン)をクリックし、「Pydev」→「Pydev Project」を選択し、「Next」をクリックしましょう。
  3. プロジェクトの作成画面では適当なプロジェクトフォルダ名(今回はwxPing)、PythonのVersion(今回は2.6)をセットして「Finish」をクリックします。
  4.  これで空のPythonプロジェクトが作成されます。
    続いてですが、ひとまずこちらは置いときまして、wxGladeによるGUI作成に移ります。
  5. wxGladeを立ち上げましょう。まず最初は「Add a Frame」で土台となるフレームの作成ですね。
    クラス名は気分的に"wxPingFrame"とでもしておきましょうか。
  6. 追加したフレームのプロパティにて、フレームの名前とタイトルを適当(わかりやすいよう)に設定します。今回はフレーム名を"frame_ping"、タイトルを"wxPing"とします。
  7. 画面要素を追加していきますが、まずは縦に2段必要ですね。
    スロットを一つ追加するためには、ツリーにてframe_pingの下にあるsizer_1を右クリックし「Add slot」を選択します。
  8. sizer_1が上下2つに分割されましたね。sizer_1の上のスロットは、さらに横に3分割したいのでSizerを追加します。「Add a BoxSizer」を選択して、上のスロットをクリックしましょう。Orientationは「Horizontal(水平方向)」、Slotsは「3」で作成します。
  9. 追加されたsizer_2の方には、左側から順に「Add a StaticText」、「Add a TextCtrl」、「Add a Button」。残ったsizer_1の下のスロットには「Add a TextCtrl」を追加しましょう。それぞれ適当にタイトルと名前を設定しておきます。
    (今回は"label_dist"、"text_ctrl_dist"、"button_ping"、"text_ctrl_result"とします)
  10. (ビューのレイアウトがおかしい件は置いときまして、)それぞれのアイテムに基本的なレイアウトを設定(プロパティの「Layout」タブで設定)しましょう。
    "label_dist"、"text_ctrl_dist"、"button_ping"、"text_ctrl_result"に全てに共通でBorderを"5"、wxALLにチェック(上下左右に5ピクセルの余白をつける)、wxALIGN_CENTER_VERTICALにチェック(縦に向かって中央に配置)します。
    "text_ctrl_result"にのみwxEXPANDにチェック(親の大きさに合わせる)します。
  11. なお、実際に実行したときの画面イメージは、メインのフレーム("frame_ping")のプロパティの「Preview」ボタンをクリックして表示させることができます。プレビューを見ながら、画面構成の問題点を見つけて解消していきましょう。
  12. まず一つ目は、"text_ctrl_dist"の入力欄が小さすぎて入力を確認しずらいということがあげられます。サイズを変更する必要がありますね。
    "text_ctrl_dist"のプロパティの「Common」タブを開き、「Size」のパラメータに変更を入れるためチェックをつけます。サイズが変更可能になるので、横幅を大きめに設定しましょう。
    変更を確認するにはPreviewを一旦閉じて、11.の手順で再度表示させます。
  13. 次の問題点は、Previewのウィンドウの底をドラッグしてサイズを大きくさせたときに現れます。
    "text_ctrl_result"の縦幅は変わらず、sizer_2に乗っている部分だけが移動してしまいます。
    これはBoxSizerはデフォルトでサイズ変更に合わせてレイアウトが再調整されるのに対し、TextCtrl等はデフォルトでは固定のままとなっていることが原因のようです。逆の方がいいですよね。
  14. これを解決するには、sizer_2にてProportionの値を"0"に、"text_ctrl_result"の「Layout」タブの同じくProportionの値を"1"に変更しましょう。Proportionを0に設定するとサイズ固定に、1に設定すると全体のサイズに合わせて伸縮するようになります。
    ついでに"text_ctrl_result"の初期サイズも「Common」タブのSizeにて変更しておきます。
  15. 続いてはアイテム固有のパラメータを設定していきます。
    "text_ctrl_result"について、プロパティの「Widget」タブを開き、「wxTE_MULTILINE」(テキストを複数行にする)、「wxTE_READONLY」(キーボード入力禁止)にチェックをつけます。
    プログラムからの書き込みだけを表示させるようにするという処置です。
  16. 仕上げはボタン押下に対するイベントハンドラを設定します。
    "button_ping"のプロパティの「Events」タブにて、EVT_BUTTONというイベント(ボタン押下)に対し、"OnButtonPing"というハンドラーが呼び出されるようにします。
  17. 以上でGUIの設計は一通り完了です。コードを出力しましょう。
    Applicationのプロパティで、先に作成しておいたElicpseプロジェクトのソースフォルダ(~/workspace/wxPing/src/wxPing.pyとか)に保存しましょう。
  18. wxGladeでのGUI設計ファイルも、wxGladeのメインウィンドウのFile→Saveで保存できますので保存しておいたほうが良いでしょう。(ソースコードと同じく ~/workspace/wxPing/src/wxPing.wxgで良いです。)
  19. Eclipseのプロジェクトに戻り、動作実装に移ります。出力したはずのソースファイルが表示されていない場合はプロジェクトのフォルダを右クリックし、「Refresh」して再読み込みしてみましょう。
  20. wxPing.pyを開き、ソースファイルの修正に移ります。今回はpingを実行して結果を受け取るためにsubprocessモジュールのPopenを使いたいと思いますので、subprocessパッケージを追加します。(5行目のimport wxの下辺りに追加する)
    import wx
    from subprocess import *
    
  21. 実際に動作を記述する部分は、ボタン押下時のイベントハンドラの部分のみです。先ほどのwxGladeで自動生成されたコード(OnButtonPing)部分は以下のようになっていると思います。(50行目あたり)
  22. この部分に以下のようにpingを送信するコードを記述します。
  23. 以上でプログラミングは完了です。では実行してみましょう。EclipseプロジェクトのwxPing.pyを右クリックし、「Run As」→「Python Run」でEclipse上で実行することができます。
    こんな感じに動きましたでしょうか。

いちおう以下がソースコード全文です。


以上。簡単だったでしょ?
ま、実際の活用方法は工夫次第ということですが。

0 件のコメント:

コメントを投稿