ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

VS2005でGUIを作ってIronPythonで制御するやり方

先のネタで、IronPythonApiReference.chm があるよ。って紹介したのですが、これを元に、Visual Studio 2005でGUI(Windows Form)を作って、IronPythonで制御するやり方を調べてみました。
結論としては、非常に簡単に実現できます


以前、Python + Delphiな P4D を使いましたが(もっと楽にGUIとの連携がしたい:Python + Delphi = P4D(Python for Delphi) )、IronPythonは、これと同じか それ以上に、Python + .NET な環境を提供してくれるようです。


という訳で、実際に、Visual Sutdio 2005でGUI(Windows Form)を作って、ボタンを押したら IronPython からGUI上の部品にアクセスするコードサンプルを作ってみます。

  1. Visual Studio 2005で、Window Formを作る
  2. IronPython.dll を持ってきて、参照に追加する
  3. まずはコードを追加する
  4. とりあえず実行
  5. 処理内容の解説
  6. まとめ

1.Visual Studio 2005で、Window Formを作る

Visual Stuido 2005を起動し、Window Formを作りましょう。
とりあえず、「新しいプロジェクト」を開き、「Visual C#」→「Windows」→「Windowsアプリケーション」を選択します。
IronPython1
IronPython1 posted from フォト蔵


フォームデザイン画面では、下図のように、3つのテキストボックスと1つのボタンを配置します。
IronPython2
IronPython2 posted from フォト蔵

  • 1番上のテキストボックスが、textBox1
  • 2番目のテキストボックスが、textBox2
  • 3番目のテキストボックスが、textBox3
  • 中央のボタンが、button1

という事にします。

2.IronPython.dll を持ってきて、参照に追加する

IronPythonの実行ファイル(ipy.exe)と同じディレクトリに、IronPython.dll というアセンブリモジュールがあります。
これを、作ったプロジェクトの参照に追加します。
以下のように。
IronPython3
IronPython3 posted from フォト蔵


追加に成功すると、ソリューションエクスプローラに、IronPythonアセンブリモジュールが追加されます。
IronPython4
IronPython4 posted from フォト蔵

3.まずはコードを追加する

とりあえず、ボタンをダブルクリックし、Form1.csファイルを開いた後、以下のようにコードを書き込んでみて下さい。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using IronPython.Hosting;
using IronPython.Modules;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        private PythonEngine engine;

        private void PyInit()
        {
            engine = new PythonEngine();
            engine.Globals.Add("Form1", this);
            engine.Globals.Add("textBox1", this.textBox1);
            engine.Globals.Add("textBox2", this.textBox2);
        }
        public Form1()
        {
            InitializeComponent();
            PyInit();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            engine.ExecuteFile("..\\..\\test.py");

            string v = engine.EvaluateAs<string>("retval");
            textBox3.Text = "retval=" + v;
        }
    }
}

更に、Form1.csと同じフォルダに、以下のtest.pyファイルを作成して下さい。

import sys

cnt = int(textBox1.Text)

for i in range(cnt):
    textBox2.Text += "loop %d" % (i)
    textBox2.Text += "\r\n"

retval = str(cnt)

4.とりあえず実行

コンパイルして、実行してみて下さい。


上のテキストボックスに数値を入力し。
IronPython5
IronPython5 posted from フォト蔵


ボタンを入力すると、真ん中と下のテキストボックスに何やら値が書き込まれます
IronPython6
IronPython6 posted from フォト蔵


この値は、先のtest.pyでIronPythonから書き込まれたものです。

import sys

cnt = int(textBox1.Text)              # ここで、上のボックスから値を取り出してます。

for i in range(cnt):
    textBox2.Text += "loop %d" % (i)  # ここで、真ん中のボックスに値を書き込んでいます。
    textBox2.Text += "\r\n"

retval = str(cnt)                     # ここで、retvalという変数に値を書き込んでいます。(C#側で取得し、下のボックスに表示しています)

5.処理内容の解説

処理は、以下の順序に進んでいます。

  1. PyInitメソッドでIronPythonエンジンの初期化を行います。
    ここでは、engine.Globals.Add()メソッドを使って、C#で作ったWindow Formのフォームやテキストボックスを、IronPythonから操作できるように設定します。
  2. 上のテキストボックス(textBox1)に数値を入力し、ボタンを押すと、button1_Clickメソッドに処理が移ります。
  3. "engine.ExecuteFile("..\\..\\test.py");"で、test.pyのコードを、IronPythonエンジンで処理が行われます。
    test.pyでは、3つのブロックに分かれており、以下の処理で進みます。
  4. 上のテキストボックス(textBox1)から、入力された数値をcnt変数として取り出します。
  5. forループで入力された数値(cnt)分ループしつつ、真ん中のテキストボックス(textBox2)に文字列を書き込みます。
  6. 入力された値を、retvalという変数に書き込み、test.pyの処理が終わります。
  7. C#のコードに戻った後、"string v = engine.EvaluateAs("retval");"で、IronPythonで書き込まれたretval変数の値を文字列として取り出します。
    (stringをintにすると整数として取り出せるようです)
  8. 取り出した文字列を少し加工して、下のテキストボックス(textBox3)に書き込みます。


勝利の鍵は、engine.Globals.Add()メソッドで、C#の世界とIronPythonの世界を共有させる所でしょうか?
これにより、IronPythonから容易にC#のオブジェクトを操作できるようになります。

6.まとめ

IronPythonC#(VisualBasic)との組み合わせは、非常にスムーズに行えます。


.NETな方は、IronPythonは、オブジェクト間を繋ぐ糊として期待されるのでは無いか?と思います。
オブジェクトをengine.Globals.Add()メソッドでIronPythonに公開するだけで、IronPythonから制御できるという事は、.NETアプリケーションに、非常に簡単にスクリプト言語機能を導入できるという事でもあります。
(C#で全てを完結する場合、CodeDOMであれこれやる必要がありますからね)


Pythonな方は、Visual Studioの高度なフォーム設計機能を最大限活用し、GUIアプリケーションの外側を作り、後は自分のよく知っている Python コードで埋めるという作業に分割する事が出来ます。
一種のMVCのように扱えるという訳です。