Python3に移行する際に問題になるのが、どのGUIライブラリを使うかということです。Tkinterは見た目がイマイチ、wxWidgetsは32bitのみ対応、Gtk+, FLTK, FOXなんて知らないし、OpenGLでGUIを作るとか面倒すぎるでしょ、となるわけです(http://docs.python.org/3/faq/gui.html)。いろいろと考えた末、Qtを使うことにしました。Qtのメリットは、
- 64bit対応
- 見た目がカッコイイ!(これ重要)
です。さらに、PyQtというbindingがあって、これはPython 3に対応済みなのです!つまり、最近のスタンダードである、Python3 + 64bitをちゃんと満たしているわけです。
以下では、Mac OS Xでの具体的な使い方を紹介していきます。
インストール
- PyQtX
- Qt libraryと、PyQtと、SIPをMac用にビルドしたものだそうです。Qtは巨大すぎてmakeするだけでも一晩かかるので、ここからダウンロードすることをおすすめします。ほんまPyQtXには感謝ですm(_ _)m
- PyQtX+_py323_q482_pyqt494.pkg を使用。
- http://sourceforge.net/projects/pyqtx/
- Python 3.2.3
- PyQtXのバージョンに合わせたPythonをインストールします。
- http://www.python.org/download/releases/3.2.3/
ちなみにみーの環境は、Mac OS X 10.8.2 (Mountain Lion) です。
/Developer/Applications/Qt/ に開発ツールがインストールされますのでこのフォルダを/Applicationsに移動させると便利です。
使用方法
Designer.appを起動します。Designerでは部品を配置していくことでGUIを作成していきます。上部のメニューバーは、
このようになっていると思います。赤丸で囲ったところが編集モードを切り替えるボタンで、
- Edit Widgets : 部品の場所や属性を編集する。
- Edit Signals / Slots : シグナル・スロット(マウスイベントetc.)を設定する。
- Edit Buddies : Labelと入力を一対一で対応(buddy)させるモード。
- Edit Tab Order : タブでのフォーカス移動の順番を指定する。
http://doc.qt.digia.com/qt/designer-editing-mode.html
の4つのモードを切り替えます。流れとしては、Edit Widgetで全体の骨格を完成させたあと、SignalやBuddiesを設定していく感じでしょうか。
Widgetモードで、部品を配置していきます。例えばこんな感じですね。QSpinBoxとQDialとQSliderを配置して、Layout Managerを設定した状態です。
次に、Signals / Slotsモードにして、動作を設定します。ここでは、QSpinBoxの値と、QDial及びQSliderが連動するように設定してみました。
Sender(Signalを発生させる部品) のSignal(例えばvalueChanged(int)など) に対して、Receiver(Signalを受け取る部品) のSlot(Signalが呼び出す関数) を指定していくわけです。エディターの中央の部品をドラッグ・アンド・ドロップしていくだけなので、すごく簡単です。
この状態でPreview (Cmd+R) してみます。下のように、QSpinBoxとQDial及びQSliderのいずれかをいじると、他が連動します。
uiファイルからPythonコードを出力する
普通はpyuic4というツールを使うらしいのですが(http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/designer.html)、PyQtXでインストールするとpythonスクリプトしかついてこなかったので、/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/PyQt4/uic/にあるpyuic.pyを直接使用することにします。
cd /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/PyQt4/uic/
python3.2 pyuic.py <xxx.ui>
これでpythonスクリプトが生成されます。先ほどの例をpyuicで変換したところ、このようになりました。