Programming」カテゴリーアーカイブ

Windows 7 で IronPython そのさん

WPF にてコードでメニューを作る方法がイマイチ解らない。
というか作れたとしてどう考えてもベタ打ちな方法しかできないだろう。

ここは GtkUIManager のように XML で綺麗に作りたい。
そのための XAML じゃないか!
でもメニューとか個別パーツのみを XAML にするってできるのかな?

ということでやってみた。

いくら探しても文字列から XAML を読み込む方法が見つからない。
CLR にはデルヒャァの TStringStream みたいなのは無いの?
しかたがないので XAML ファイルを別に用意する。

<Menu
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <MenuItem Header="ファイル(_F)">
        <MenuItem Header="開く(_O)" InputGestureText="Ctrl+O" Name="menu_open" />
        <Separator/>
        <MenuItem Header="終了(_Q)" InputGestureText="Ctrl+Q" x:Name="menu_close" />
    </MenuItem>
</Menu>

というメニューのみの XAML を仮に作ってみた。
一番の親に CLR 名前空間定義は必須のようです。

IronPython はコンパイルしないので InitializeComponent() できない。
ので XAML 内でハンドラ指定はできないようだ、いくら試してもエラーばかり。
とりあえず上記に ui.xaml という名前を付けて。

# -*- coding: UTF-8 -*-

import sys
import clr

clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")

from System import *
from System.Windows import *
from System.Windows.Controls import *
from System.IO import *
from System.Windows.Markup import XamlReader

class MoviePlayer(Window):
    def __init__(self):
        self.Title = "メニューだよ"
        # Menu を GtkUIManager 風に読み込む
        # ようにしたいけど今はこれが精一杯
        i = sys.argv[0].rindex("\\")
        xaml_path = sys.argv[0][:i] + "\\ui.xaml"
        f = FileStream(xaml_path, FileMode.Open, FileAccess.Read)
        _menu = XamlReader.Load(f)
        DockPanel.SetDock(_menu, Dock.Top)
        _menu.Items[0].Items[0].Click += self.on_open
        _menu.Items[0].Items[2].Click += self.on_close
        # DockPanel
        dpanel = DockPanel()
        dpanel.LastChildFill = False
        dpanel.Children.Add(_menu)
        # self
        self.Content = dpanel
        self.Width = 320
        self.Height = 240

    def on_open(self, sender, e):
        MessageBox.Show("わーい")

    def on_close(self, sender, e):
        self.Close()

if __name__ == "__main__":
    a = Application()
    a.Run(MoviePlayer())

menu_first

何をやっているかはなんとなく解ると思う。
とりあえずパーツのみの XAML は可能だと解った。
少しだけ GtkUIManager 風に作れたが Items の順番でハンドラ指定では…

ウインドを作る( PyGtk+Glade )

の最後みたいな処理を作るしかないかな?それはそれで難しくは無いけど。
もっと Name プロパティからスマートに指定できそうなんだけど…続くかも。

Windows 7 で IronPython そのに

一般的な互換性問題 – Windows 7 対応アプリケーションの互換性

Windows 7 で最初からブロックされないようにする方法はそんなに難しくは無いわけだ。
しかし個人オンラインソフトごときにこんな大げさななことをするか…minipoli とかに。
少なくとも私はそんなことまでして公開なんかしたくないよ。

「こんなのを作ったので気に入ったら使ってくれい!」
なんて文化が Windows にはあったのが懐かしい、もうユーザーのほうが求めていない?

MS はエクセルとワードとパワポを利用するためだけの OS にしたいらしい。
でもやっぱり Windows しか使えない人ばかりなのでみんな疑うことなく Windows を選ぶ。

Ubuntu のほうがいいよ、けどこれ Windows じゃないから。
ということで書名が必要な拡張子をよくみてよ。

拡張子 .exe、.dll、.ocx、.sys、.cpl、.drv および .scr のついたファイルが対象

C# で作ると *.exe になるね。

*.py は無いじゃん。

Windows 7 で .NET Framework は IronPython の時代になる!

かもしれない。

しかし IronPython で奇妙なことに気がついた。
騙されたと思ってコレを実効してみよう。

#-*- coding:utf-8 -*-

s = "あいうえお"
i = 12345

print dir(s)
print dir(i)
print "\n"
import System

print dir(s)
print dir(i)

dir

s や i は当然 str や int という Python の型になる。
しかし System をインポートした時点で System.String や System.Int32 としても使える。
恐ろしいのはどっちでもいいということである、動的言語の凄さを見た。
面倒な型変換は不要だし両方のメソッドが利用できるということである。

C++/CLI のマーシャリングっていったい何? IronPython なら全自動じゃん。
以前書いたように P/Invoke なんて不要になる、 ctypes モジュールが使えるようになる。
ライバルになりそうなナントカビーは他人が読みにくいコードを書くのに命を掛けるだろう。
元々「 C# で var 使っているの?ププッ」な言語でもある。
VB …何それ知らないんだけど?

ということで IronPython の時代がやってくる、はず…

Windows 7 で IronPython

WPF を Microsoft の思想を無視こいて単なるウインドウ部品として使うのは面白い。
しかし Ubuntu 上 VirtualBox のゲストな XP で使っていて一番困っていること。

Windows XP の .NET Framework は死ぬほど遅い!

もう Vista はほとんど使わないのでコイツもゲスト OS にしてしまおうか?
何度も書いているが Vista なら .NET Framework も初回起動以降は実用レベル。

でもそれではライセンスがもったいない、HDD ブートで使いたくなる場合もある。
何よりこれまでに作り上げた環境をゼロから作り直しなんてご勘弁。
一時間あれば再構築が完了するほどデフォルトが充実した Ubuntu のようにいかない。
んー何か良い方法は…

そうだ、Windows 7 RC という手があった!

こいつは Windows 6.1、単なる Vista メーカーチューニング版。
なので Vista とほぼ同じように動かせるはず。
最新版 .NET Framework も PowerShell も標準装備だったはず。
利用する開発環境の IronPython は数メガバイト、構築も簡単。
VirtualBox のゲスト OS にして IronPython テストが目的だから RC で十分。
なんだよ、いいことだらけだ。

IE でないと iso を落とせないだろうから vista HDD につなぎ替え。
起動すると Windows Defender が「スキャンされていません」だと。
一ヶ月も電源を入れていないのにスキャンも糞もあるか!ふざけるな!
こういう部分で Windows が嫌になる、こんなことより sudo を用意しろよ。

IE から Windows 7 で検索、あっという間にダウンロードページへたどり着く。
2.52 GB か、何故にこんなにデカいやら、とにかく落として DVD-R に焼く。

Ubuntu 9.04 の HDD に戻してインストール開始。
VirtualBox ose には普通に Windows 7 のインストール項目があって驚く。
仮想 HDD は可変の 20GB、メモリ割り当ては 512MB に一応指定して開始。

インストーラは超親切、説明はアホらしいので割愛。

とりあえずインストールが終わった時点で vdi のサイズは 5.2GB だった。
やっぱりデカいなぁ、本当にサクサク動くか心配。

一度シャットダウンして起動時間を、ユーザー選択画面まで私の環境で約 100 秒。
XP は 20 秒、本当はちーとも Vista から早くなっていないのは予想どおり。

デフォルト状態で解像度が変更できる、これは驚いた。
というか VirtualBox ドライバーが標準装備なんだ、でもワイド画面には未対応か。

vga

他パフォーマンスは以下、メモリ使用量は Vista の約半分になっているのは本当みたい。

power7

よしよし、これなら十分実用範囲だ。
Windows Power Shell も標準で入っていて XP で使うより数倍早い、これなら使う気になる。
とりあえず以下をダウンロード&インストール。

IronPython 2.0.1
EmEditor 8.0.5
FileZilla 3.2.4.1

使用期限があるんだから他はいいや、メーラーはマジで最初は入っていないのね。

あれ?Program Files 以外で EXE を起動させると警告画面が出るようになった。
(ちょっと違っていた、追記で)
これは素晴らしい、やっとその気になったか…てか遅すぎだよ。
アプリ作りは面倒になるだろうけどセキュリティを考えると当然の選択なのに今まで…
これがあるので IronPython は msi 版を入れたけどインストーラでパスくらい通してくれよ。

でもこのせっかくのセキュリティを OFF にする Tips ページが乱立するんだろうなぁきっと。
んでセキュリティソフトを売ろうと必死になるのは今までどおりと。

しかしこれは…

メモリ使用量以外に Vista からの進化を何一つ感じない、まさしく 6.1 。
Explorer は更に使いにくい、余計なことはしないで普通の階層表示に戻してくれ!
タスクバーの結合機能は酷い、ランチャ状態なのかタスクの最小化状態なのか判別し辛い。
の改悪点ばかりが気になる。

それはともかく .NET Framework と WPF だが昨日のコードは問題なく動かせる。

player

はっきりいって現在 Vista を利用中の人が買い換える理由はゼロに等しい感じ。
まあいいや、512MB 程度のメモリ割り当てでも動くんだから仮想にして遊ぶには丁度良い。
でも ipy.exe が Vista ほど早く動かない、メモリをもっと割り当てなきゃダメ?

追記

やっぱり開発に不便なので minipoli と ExpLZH くらいは必要か。
あれ? Explorer が標準で LHA の解凍ができるようになっているぞ。
と、喜んで早速 minipoli を Program Files に突っ込んだのだが。

app

ぅおーーーーーーい!

Program Files に入れてもブロックされてもーた。
プロパティを見たらコレ、そういうことだったのか。
もうアーカイブを展開するだけで使える Windows アプリは全滅だ。

「こうやってブロックを解除してください」

なんてサイトに書いてもわざわざそんなのやる人は余程のヲタだけだ。
一般の人には信頼できないアプリの烙印を押されて終わり。
Windows 7 正式版が出る前に minipoli もインストーラを作らないとまずい。
minipoli だけでいいや(ぉい!

IronPython で簡単動画再生

川西 裕幸のブログ : Media Foundation の更新 @ Windows 7

Windows 7 の Media Foundation は H.264 もサポートらしい。
WMV 以外はまともに再生できなかったのに、FLV は流石にサポートしないか。

せっかくなので IronPython で動画再生方法、書くまでもなく WPF。
もちろん System.Windows.Controls.MediaElement を使います。
こいつが Media Foundation のフロントエンドです。

# -*- coding: UTF-8 -*-

import clr

clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")

from System import *
from System.Windows import *
from System.Windows.Controls import *

class MoviePlayer(Window):
    def __init__(self):
        self.Title = "動画プレイヤー"
        # System.Windows.Controls.MediaElement
        self.player = MediaElement()
        self.Content = self.player
        self.Width = 320
        self.Height = 240
        # D&D
        self.AllowDrop = True
        self.Drop += self.on_drop

    def on_drop(self, sender, e):
        # System.Array なので str に変換
        filenames = e.Data.GetData(DataFormats.FileDrop)
        filename = str(filenames[0])
        if filename != None and filename.Length != 0:
            self.player.Source = Uri(filename)

if __name__ == "__main__":
    a = Application()
    a.Run(MoviePlayer())

konko

自分で作って驚いたけど VirtualBox のゲストである XP で動いてしまった。
Cinema は動かなかったのに、というより DirectX 使いまくりなのに普通に動くとは。
DirectShow は関係無く現状では WMV しかまともに再生できませんけどね。

Windows 7 でやってみてアリなら作り込んでみるのも面白いかも。
7 を買うかどうかは…これなら VirtualBox のゲストにするのもいいかも…

グラフィックコンテキストの色はもっと簡単に変更できた

グラフィックコンテキストの色はもっと簡単に変更できた

set_rgb_fg_color(gtk.gdk.color_parse("red"))

で expose-event の中でも CPU 負荷もなくアッサリ変更できる。
GTK+ はデフォルトがダブルバッファリングなのでチラツキも全然無い。
チビッと試しに書いてみた。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import gtk
import pango

ui_str = """<ui>
    <menubar name="MenuBar">
        <menu action="File">
            <menuitem action="quit"/>
        </menu>
    </menubar>
</ui>"""

class GC_Test(gtk.Window):
    """
        GC で色々な表示を試してみる
        Font を変更するには pango を使う必要があるのね
    """
    def __init__(self):
        # お約束
        gtk.Window.__init__(self)
        # GtkUIManager 作成
        uimanager = gtk.UIManager()
        # GtkAccelGroup を取り出し self にて突っ込む
        accelgroup = uimanager.get_accel_group()
        self.add_accel_group(accelgroup)
        # GtkActionGroup 作成
        actiongroup = gtk.ActionGroup("nandemoii")
        # GtkActionEntry の list を作成して GtkUIManager に突っ込む
        e = [("quit", gtk.STOCK_QUIT, "終了(_Q)", "<Control>Q", "さいなら", self.on_quit),
            ("File", None, "ファイル(_F)") ]
        actiongroup.add_actions(e)
        # GtkUIManager の更新
        uimanager.insert_action_group(actiongroup, 0)
        uimanager.add_ui_from_string(ui_str)
        # メニューを取り出す
        menubar = uimanager.get_widget("/MenuBar")
        # パッキング
        statusbar = gtk.Statusbar()
        drawingarea = gtk.DrawingArea()
        #
        # ダブルバッファリング無効状態にしたいならココを有効にしてね
        #drawingarea.unset_flags(gtk.DOUBLE_BUFFERED)
        #
        # WM_PAINT のようなものを発生させる
        drawingarea.connect("expose-event", self.on_drawingarea_expose)
        # パッキング
        vbox = gtk.VBox()
        vbox.pack_start(menubar, False)
        vbox.pack_start(drawingarea)
        vbox.pack_end(statusbar, False)
        self.add(vbox)
        # いつもの処理
        self.set_title("gc_test")
        self.connect("delete-event", self.on_quit)
        self.resize(320,240)
        self.show_all()

    def on_quit(self, widget, event=None):
        gtk.main_quit()

    def on_drawingarea_expose(self, widget, event=None):
        # グラフィック・コンテキストを得る
        gc = widget.style.fg_gc[gtk.STATE_NORMAL]
        # 赤くする
        gc.set_rgb_fg_color(gtk.gdk.color_parse("red"))
        # 自分のサイズ取得
        d_width = widget.allocation.width
        d_height = widget.allocation.height
        # 塗りつぶす
        widget.window.draw_rectangle(gc, True, 0, 0, d_width, d_height)
        # 緑色にする
        gc.set_rgb_fg_color(gtk.gdk.color_parse("green"))
        # Font を大きくして文字列描写
        font_desc = pango.FontDescription('Monospace 32')
        layout = widget.create_pango_layout ("まっかっか")
        layout.set_font_description(font_desc)
        widget.window.draw_layout(gc, 10, 20, layout)
        # 青色にする
        gc.set_rgb_fg_color(gtk.gdk.color_parse("blue"))
        # 線
        widget.window.draw_line(gc, 0, 0, d_width, d_height)

if __name__ == "__main__":
    w = GC_Test()
    gtk.main()

makkakka

これでどこをどう書けばどういう表示になるか簡単に解る…と思う。
2D にしてグリグリウインドウサイズを変更するとチラツキが無いのも理解できる。
ダブルバッファリングを無効にする方法もついでに。

PyGtk って何でもやれて面白いですよ。

keywords

今月も mono が多い…そんなに Linux で C# なんかやりたいの?
キッカケだけならそれでいいけど、私がそうだったし。