exe ファイル化

py2exe による exe 化に成功しました。環境は以下の通り。

まずリソースですが、 XRCed からリソース用 python スクリプトを出力します。

  1. File -> Generate Python でダイアログを開く
  2. Embed resources in the Python module にチェックを入れる
  3. pywxrc_xrc.py という名前でリソースを利用するスクリプトと同じフォルダに保存する

これで、リソース用の XRC を含むモジュール用スクリプトが作成されます。

次に出力されたリソースモジュールを利用するアプリケーションのスクリプトです。

#coding: utf-8
import wx
import wx_utils
import pywxrc_xrc
from wx_utils import XRC, XRCID, XRCCTRL

class MainFrame(pywxrc_xrc.xrcID_MAIN_FRAME):
    binder = wx_utils.bind_manager()
    
    list_ctrl_col = [
        u'ユーザ',
        u'グループ',
        u'ホスト',
        u'IPアドレス'
    ]
    
    def __init__(self, parent=None):
        pywxrc_xrc.xrcID_MAIN_FRAME.__init__(self, parent)
        # イベントハンドラ関連付け
        self.binder.bindall(self)
        # コントロールを取り出し
        ctrl=XRCCTRL(self, 'ID_LIST_USERS')
        # 行を追加
        for idx, col in enumerate(self.list_ctrl_col):
            ctrl.InsertColumn(idx, col)

    @binder(wx.EVT_BUTTON, id=XRCID('ID_BTN_SEND'))
    def OnClickBtnSend(self, event):
        ctrl=XRCCTRL(self, 'ID_TEXT_MESSAGE')
        print ctrl.GetValue()

if __name__=='__main__':
    app = wx.App(False)
    frm = MainFrame()
    app.SetTopWindow(frm)
    frm.Show()
    app.MainLoop()
  1. リソースモジュール pywxrc_xrc をインポートする
  2. pywxrc_xrc.xrcID_MAIN_FRAME*1 を継承したメインフレームクラスを定義する。
  3. wx_utils.XrcInit() は呼び出さない(pywxrc_xrc.xrcID_MAIN_FRAME の初期化時に同等の処理を行っています)。

最後に py2exe で exe ファイル化する処理です。

import sys
from distutils.core import setup
import py2exe
import wx.tools.pywxrc as pywxrc
from wx_utils import manifest

if not 'py2exe' in sys.argv:
  sys.argv.insert(1, 'py2exe')

py2exe_options = {
    "compressed":1,
    "optimize":2,
    "bundle_files":1
}
setup(
    options = {"py2exe": py2exe_options},
    console = [{
        "script" : "ipmsg.py",
        "icon_resources": [(1,"icon1.ico")],
        'other_resources': [(24,1,manifest('ipmsg.py'))],
    }],
    zipfile = None)

ほぼサンプルそのままの setup.py です。ただ、元の wx_util.manifest の中では pywxrc でリソースの xrc を python モジュールに変換しています。これは既に XRCed で行っているので不要です。出力するファイル名がかぶったりしたらややこしいことになるので、この処理は削除させていただきました。

def manifest(app_name):
  #不要 os.system('pywxrc -p resource.xrc')

この setup.py を実行すると、 dist ディレクトリに ipmsg.exe が作成されます。今回は Python 実行環境や DLL まで全てを含めているので 6 MB の巨大な実行ファイルになってしまいました。でも昨今の PC の性能を考えれば、お手軽に使ってもらえるのでまぁよいのではないかな。

イベントハンドラのバインドには、 wx_utils.py の bind_manager を利用させていただいていますが、 XRCed でもイベントハンドラを出力することが出来るようになっています。 pywxrc_xrc.py の中にイベントハンドラのメソッドが組み込まれているのでカスタマイズの方法がちょっとややこしそうな予感がします。気が向いたら調べてみようかなと思います。

*1:クラス名は、XRCed で指定した名前の前に xrc をつけたものになります。