投稿者「sasakima-nao」のアーカイブ

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# なんかやりたいの?
キッカケだけならそれでいいけど、私がそうだったし。

IronPython2.6beta を試す

IronPython – Release: 2.6 Beta 1

DevHawk – IronPython 2.6 Beta 1

どうやら IronPython 2.6 には ctypes が追加されるみたいなんだが。
面白そうなので落としてみる。

ipy26b1

なんかイッパイファイルが増えているなぁ。
とりあえずインタラクティブシェルで試してみるか。

errer

だめヤン、やりかたが悪いのかな?

そういえば IronPython 2.0 では普通の ctypes も import できなかったっけか。
なんか os モジュールでエラーになってしまう、こっちも試してみよう。

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

import sys

# CPython 2.6 を自分がインストールしている場所
sys.path.insert(0, "C:\\Python26\\lib")
import ctypes

MB_OK = 0
MB_OKCANCEL = 0x00000001
IDOK = 1

dll = ctypes.windll.user32
res = dll.MessageBoxW(0, u"どちらかを押してください", u"たいとる", MB_OKCANCEL)

if res == IDOK:
    dll.MessageBoxW(0, u"OK を押しました", u"りざると", MB_OK)
else:
    dll.MessageBoxW(0, u"キャンセルを押しました", u"りざると", MB_OK)

IronPython 2.6 で実効。
間違えて CPython で動かしちゃダメよ。

cmd

おぉエラーにならなくなっている。
つまり普通の ctypes を使えばいいだけってことなのかな?
今は解らない、もっと情報が上がるのを待とう。

os.path.join() は理由がある

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

import os

# コレだとカレントディレクトリの場合は空文字になる
print os.path.dirname(__file__) + "/put.txt"
# 正確に行う方法
print os.path.abspath(os.path.dirname(__file__)) + "/put.txt"

output

今頃知った。
ま、実用上は絶対パスにしなくても得に問題は…ある!

このままだとファイル名の先頭がパス区切り文字になる場合があるってことじゃないの。
os.path.join() で合体しろと強調する理由はコレだったのね。
単純にパス区切り文字を振り分けというくだらない理由だけじゃなくて。

それよりこうやって Linux と Windows での表示を比べると…
せめて PowerShell だけでも Windows の標準カレントディレクトリをなんとかしてほしいわ。
変更できるのは解っているけど最初から C:\ユーザー名 でいいじゃないか。

GtkMenu.popup で左右両ボタン認識は簡単だった

今日はこのページを作っていたのだが

ドロップされた画像を表示させる

ここで今まで右クリックメニューを出すコードに右ボタンを指定を忘れていたことに気がつく。
ごまかす為に以前のページを書き換えていたのだが

if event.button == 3:
    self.popup_menu.popup(None, None, None, event.button, event.time)

event.button を何故二回も使っていたのだろう。
Devhelp を改めて見直すと popup の四番目引数はボタンの指定だ。
つまりメニューアイテムの選択を確定させるボタンということである。

あぁだからポップアップの入れ子は右ボタン(つまり 3 )しか反応しないのか。
ここに左を示す 1 を含めた値…int なんだから 4 になって全然違うボタンの指定になってまうし…
だったらゼロにするとどうなる?

if event.button == 3:
    self.popup_menu.popup(None, None, None, 0, event.time)

コレであんなに悩んだ入れ子メニュークリックでの左右両ボタンでの確定がアッサリ解決…
何故こんな単純なことに今まで気がつかなかったのだろうか…
これだけで Y901x を更新するのもアレなので今度まとめてにしよう。