PythonのGUIアプリを(VB.NETで)書こう
どーも。今回はPythonのクラスをVB.NETから呼び出して、既存PythonソースとGUIとの橋渡しをしたいと思います。
Pythonのベジェ曲線クラスをVB.NETから呼び出してハートマークを書いたの図
PythonでのGUI開発
Pythonで書いたスクリプトの機能をGUI化したい。そういう時の選択肢は大体こんなもんじゃないでしょうか。
名前 | 説明 |
---|---|
Tkinter | Pythonディストリビューションの標準ライブラリ |
PyGTK | クロスプラットフォームGUIライブラリGTKのPythonバインディング |
wxPython | クロスプラットフォームGUIライブラリwxWidgetsのPythonバインディング |
PyQt | 同じくGUIライブラリのQtのPythonバインディング |
PySide | PyQtのライセンス違いらしい。 |
で、TkinterとwxPythonをいじって、PythonでGUIプログラムを組むときの問題点だなーと感じたのが
- GUIプログラミングは関連するクラスが多いので、どういう時どのクラスを利用すればいいのか、どのプロパティを変更すればいいのかが、すぐにはわからない。
- にも関わらず、ライブラリのドキュメントが不足している、日本語の情報どころか英語の情報もほとんど無い
- プロパティの名前などいちいち覚えていられないのに、エディタ、IDEの補完が弱い(遅い)
- クロスプラットフォームのライブラリだとしばしばバグに遭遇する
- GUIデザイナの貧弱さ、不安定さ
→ から...全然進まずに困っちゃうという。特にGUIデザイナの貧弱さは悲惨で、はじめから画面レイアウトを入念に考えて組んで、実際に使って見て調整、変更する際に結構大きく変更する必要が出たりして本当にだるい。wxPythonとか、wxWidgetsを理解してないとドキュメントだけ読んでも訳分からんとこ多いし。
.NETでやればいいんじゃね?
全然資料が無いところを暗中模索で無駄に時間を使ってうがーとなるのを繰り返すうちに、段々、散々時間かけてTkinterとかいう謎のライブラリを使ったりwxPythonみたいにまともに資料が無いものを使うよりなんかもう.NETでやればいいんじゃないのかなと考えるようになりました。どうせPyQtとかもアレなんだろ!!!みたいな。
ただ、機能に関しては既にPythonで実装しているので、.NETで実装しなおすような事はしたくない。そこで。
IronPythonで既存Pythonスクリプトのロジックを動かし、VB.NETでUIを操作するというアプローチでPythonのGUIアプリを作ってみたいと思います。
VB.NETなら
- ドキュメントが豊富
- 安定してる
- すぐ使える(Pythonが分かるなら、構文だけならほとんど労力を割かずに覚えられる
ので、適当にぐぐってコピペしてIronPythonに橋渡ししてやれば簡単にGUIをつけられるはず。
関連
IronPythonの世界 (Windows Script Programming)
- 作者: 荒井省三
- 出版社/メーカー: ソフトバンク クリエイティブ
- 発売日: 2007/03/28
- メディア: 単行本
- 購入: 4人 クリック: 31回
- この商品を含むブログ (21件) を見る
用意するもの
- Visual Basic 2010 Express または Visual Studio Express または Professional
- IronPython http://ironpython.codeplex.com/ からダウンロード、インストール
IronPythonのインストール時に、他の言語からIronPythonを利用するためのDLLファイル群が同時にインストールされます。
VB.NETアプリ実行時のIronPythonとの連携準備
- VB.NETのプロジェクトに、IronPythonのディレクトリを丸ごと追加(コピー)する。
- Libディレクトリとdllファイルを残してすべて削除する。
- [プロジェクト]→[参照の追加]から参照タブを選択してIronPythonのフォルダ以下にあるdllを全て追加する
VB.NET - IronPythonの連携
ここまで書いて置いてまだよく分かってないのですが最低限の部分だけ。
予め、プロジェクトに「PythonLibrary」という名前のディレクトリを用意して以下のスクリプトを配置されているとします。
# Greeting.py class Greeting: def __init__(self): self.hist = [] def greeting(self, name): self.hist.append(name) return 'hello %s!' % name def history(self): return self.hist
VB.NET側ではIronPythonの実行エンジンを作成してPythonスクリプトを読み込んで、インスタンスを作成したりしてデータを受け渡しします。
Imports Microsoft.Scripting Imports Microsoft.Scripting.Hosting Imports IronPython.Hosting ' ...略 Dim engine As ScriptEngine = Python.CreateEngine() ' サーチパス設定(モジュールのインポートに必要) engine.SetSearchPaths(New String() {"..\..\IronPython 2.7\Lib", "..\..\PythonLibrary", "."}) Dim scope As ScriptScope ' Pythonファイル読み込み scope = engine.Runtime.ImportModule("Greeting") ' 外部ライブラリ読み込み ' ...略 ' インスタンス作成 Dim cls As Object = engine.Operations.Invoke(scope.GetVariable("Greeter")) ' ...略 ' メソッド呼び出し Dim str As String = engine.Operations.InvokeMember(cls, "greeting", New Object() {"alice"}) ' listが戻り値の場合 Dim lst As IronPython.Runtime.List = engine.Operations.InvokeMember(cls, "history", New Object() {})
こんな感じ。BeautifulSoup等の外部ライブラリなどもこのディレクトリに入れておけば(あるいは他のディレクトリを掘ってサーチパスに追加すれば)、サードパーティーのライブラリもインポートして使えるようになります。
連携例
前に「Pythonでベジェ曲線クラスを実装してwxPythonで動かす」で実装したベジェ曲線の計算クラスの機能に、指定された4点からなる3次のベジェ曲線を描画するGUIプログラムを作ってみました。コードは以下に
https://gist.github.com/1303534
こんな事ができます。
- 4点をクリックするとそれらからなる3次のベジェ曲線を描画する。
- 1度描画された曲線の制御点は、シフトボタンを押しながらドラッグすると移動できる。
- クリアボタンを押すと全ての曲線と編集中の点がクリアされる。