Pythonでデスクトップアプリを作ろう 2010.10.5〜

【動機】
 もうJAVAだのC++だのでプログラムを作る体力もないし、かといってLinuxのコンソールアプリという時代でもないし、 というサンデープログラマの皆さんこんにちは。
 GUIアプリを1から作るのは大変面倒なのだけれど、仕事でPythonに触れる機会があり、TkInterとかちょっと弄ってるうちに、 wxWidgetというフレームワークがPythonに対応しているのを知り、GUIデザイナーも色々あって、結構悩まずにGUIアプリが 書けるということで、久し振りにプログラミングを再開してみました。折角書いたソースなので、公開しておくとこれから 始める人の参考(下手糞な部分も含め)になるかと思い、ここに置いておくことにします。
 なので、ページデザインも適当ですw

【環境構築】
● Pythonのインストール
 Pythonインタプリタは現在2.6.x、2.7.x、3.xが入手可能です。2.x系統と言うべきですが、既存のライブラリで動作確認が 取れているのは2.6あたりまでが多いので、私は2.6系の最新である2.6.6を使用してます。3.xは、大幅に仕様が変わっている ので、最新好きの人は人柱気分でどうぞ、といった感じらしい。
 入手は公式サイトのDownloadから。

● wxPython
 wxWidgetは、GUI部品やプロセス管理などをはじめとする多岐にわたるライブラリ集です。C++でも使えますが、Python で使用するためのラッパーであるwxPyhtonがあるのが特徴です。同様のライブラリにはpyGtkやpyQtなどがありますが、 インストールが簡単で、見た目が実行環境のOSと同じになるという点で、素人にも扱いやすい気がします。
 特にwxPythonのソースコードを見ながら確認できるデモがあるので、機能を引き出しやすいのは大きなメリットでしょう。
 こちらも入手はwxPython公式サイトのDownloadから。win32-unicode版をダウンロード
してください。docs-demosも拾っておくと良いでしょう。

● BOA Constructor
 wxPython対応のGUIデザイナー/開発環境はwxGladeなどいくつかありますが、ソースコード編集のしやすさからBOA Constructor というフリー開発環境を使用しています。欠点は、ソースコードエディタで日本語が使えないこと。
 とはいえ、GUIエディタでラベル文字列などに日本語を入力することはできるので、あまり不自由は感じません。
 こちらは公式サイトのDownloadから SourceForgeに行くと バイナリパッケージがあるので、そちらの最新版(0.6.1)を拾ってインストールすれば良いかと思います。

【参考リンク】
wxPyWiki - 公式サイトとここを見て、あとはデモ を参照すれば結構なんとかなります。
日本Pythonユーザ会 - Pythonに関する日本語情報は随一。
Python Matrix JP - Pyhtonに関する小技など。Py2exeの 使い方は、ここの解説が一番判り易かったかも。

【作ってみた】

▼まちつくシミュレータ
携帯アプリの「まちつく!」の町作成シミュレータです。
アイテム(建物)配置のシミュレートをしたり、手持ちアイテムの在庫と突合せを支援する事を目的に作成しました。
アイテム画像はウノウ(株)様の著作物のため同梱していません。
各自携帯の画像保存などで画像を保存し、適切な名前を付けてchipsディレクトリに保存して下さい(日本語ファイル名可)。

※ ストック情報は、machistock.ms9 というデフォルトファイル名で実行ファイルと同じディレクトリに保存しておけば、 次回起動時に自動的に読み込みます。
 ただし、ストック情報・マップデータ共に自動保存には対応していないため、適宜手動で保存してください。
実行ファイル:machisim091.zip
ソースコード:machisim091src.zip

【ここで引っかかりましたw】

● MenuBarが作れない
BOAでメイン画面のレイアウトをある程度デザイナーウィンドウで作るのは簡単ですが、Frameにメニューバーを追加 するのにちょっと悩みました。
以下の手順でコードを生成する必要があるようです。

(1)部品ウィンドウのUtilitiesタブからwx.Menuを作成し、ドロップダウンメニューのエントリを定義。
(2)部品ウィンドウのUtilitiesタブからwx.MenuBar作成し、wx.MenuBarのエントリにwx.Menuのインスタンスを紐付ける。
(3)wx.FrameのプロパティでMenuBarの項目にwx.MenuBarのインスタンスをプルダウンから設定(右図)。

メニュー選択時のコールバック定義は、wx.Menuの各エントリでEVT_MENUに割り付けるのですが、メニューバー のエントリに直接コールバックイベントを割り付けられないのは、何か技が必要なのだろうか。
仕様?

● ダイアログが二度出る
OnMenuSelectedの定義をBOAが自動生成したままだと、二度同じイベントを解釈してダイアログを閉じたのにもう一度ダイアログを表示するような 挙動を呈します。
自動生成で書かれているevent.skip()は、イベントを捨てずに転送するらしい。
要らないevent.skipはちゃんと掃除しておきましょう。

● wx.Choiceを追加したらデザイナーウィンドウが出せなくなった
プルダウンで選択肢を提供するwx.Choiceを置いて、コンストラクタのChoiceに選択肢のリストを書いたのだけれども、 次にデザイナーを開こうとしたら「文字型でなきゃダメ」というエラーダイアログが出て、デザイナーを開けなくなり ました。

よく追いかけてみると、1〜3の数値を選択するため、wx.Choiceの選択肢リストとして [1,2,3] と書いたのが原因でした。
wx.Choiceの選択肢要素として許されるのは文字列のみのようで、['1','2','3'] と書く必要があります。