【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

対話的操作 (IronPython編)

n7shi2009-06-10


昨日と同じことをIronPythonでもやってみました。Visual Studio内のIronPython Consoleから実行するとイベントループが回るためコマンドを入力しながらウィンドウを操作することができますが、コマンドプロンプトのipyからだとイベントループが回らないため表示したウィンドウを操作することができません。

WPFを読み込みます。

import clr
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")
from System.Windows import *
from System.Windows.Controls import *
from System.Windows.Shapes import *
from System.Windows.Media import *

ウィンドウを開きます。

w = Window(Title = "Test", Width = 256.0, Height = 256.0)
w.Show()

図形を置くためのCanvasを用意します。

canvas = Canvas()
w.Content = canvas

四角形を置きます。

r = Rectangle(Width = 40.0, Height = 40.0)
Canvas.SetLeft(r, 20.0)
Canvas.SetTop(r, 60.0)
r.Stroke = SolidColorBrush(Colors.Black)
r.Fill = SolidColorBrush(Colors.Cyan)
canvas.Children.Add(r)

文字を置きます。

tb = TextBlock(Text = "IronPython", FontSize = 24.0)
canvas.Children.Add(tb)

移動がCanvas経由で面倒なため関数にします。

def move(el, x, y):
    Canvas.SetLeft(el, x)
    Canvas.SetTop(el, y)

move(tb, 20.0, 30.0)

マウスで移動できるようにします。

elem = None
click = Point()
orig = Point()

def down(el, e):
    global elem, click, orig
    elem = el
    orig = Point(Canvas.GetLeft(el), Canvas.GetTop(el))
    click = e.GetPosition(canvas)
    canvas.CaptureMouse()

r.MouseDown += lambda sender, e: down(r, e)
tb.MouseDown += lambda sender, e: down(tb, e)

def canvas_MouseMove(sender, e):
    global elem, click, orig
    if elem is not None:
        p = e.GetPosition(canvas)
        move(elem, orig.X + p.X - click.X, orig.Y + p.Y - click.Y)

canvas.MouseMove += canvas_MouseMove

def canvas_MouseUp(sender, e):
    global elem
    elem = None
    canvas.ReleaseMouseCapture()

canvas.MouseUp += canvas_MouseUp

冒頭で述べたようにコマンドプロンプトのipyから実行した場合はイベントループが回らないため、明示的にイベントループを回すことで操作できるようになります。

Application().Run()

印象

F#と比較したIronPythonの使用感などです。

コンパイルしたexeの起動はIronPythonの方が遅いです。DLRの初期化の関係でしょうか。

.NETのオブジェクトを操作している限りは、F#もIronPythonも文法が違うだけという印象です。IronPythonの方が文法が簡潔で入力がスムーズです。特に対話モードのセミコロンの有無は大きいです。

型付けの静的・動的の違いについては、対話的な実行ではその場で評価されるためあまり違いを感じませんでした。プログラムとしてはIronPythonでは実行時に例外が発生するまで分からないため、動的型付けだということがはっきりします。

Pythonの構文でF#のように型推論してくれたら良いのにと思いましたが、それがBooですね。