月別アーカイブ: 2009年5月

Windows Opera を Python で

ゲストの Windows XP に入れたアプリケーション等の覚書。

.NET Framework 3.5   やっぱり必要だった
IronPython   コレを動かさなきゃいけないもん
Windows Power Shell   もうコレが無いと辛い
Windows Live   メールとフォトギャラリのみだが
IE8   何故自動更新してくれない…
WMP11   これも…

以上 Microsoft から、他

Opera   まあ私なので
Python   今回は Ubuntu に合わせて 2.6.2 を
FileZilla   コッチからサイトやブログの更新も可能なように
Paint.net   これも、もう Gimp 対向で標準にしてくれ
IrfanView   観覧にも使うけど主にスクリーンショット用
ExpLZH   圧縮する機会が多いとアーカイバーはコレしか選べない
ATOK   せっかく買ったので、Anthy のオバカ変換にも慣れたけど
EmEditor   主に Python 書き用途
秀丸   何故テキストエディタを2つも入れる?と言うな
秀丸メール   昔のメールを参照しなきゃいけない場合があるのよ
Bz   バイナリチェックをすることが多いのよ
UnitMovie   聞かないでくれ
minipoli   そりゃ自分が使う為に作ったわけで
SeeMe   そりゃ自分が使う為に作ったわけで

ホストで使うなら入れるけど見送るもの。

動画コーデック類
RealPlayer
QuickTime
VisualStudio
Firefox
Apache, PHP, MySQL
VirtualBox
他自分が作ったアプリ(仮想環境では Cinema が動かない…

最小限なのに多すぎる、、、、、

ほとんど「窓の杜」で手に入るものしか使っていないのが唯一の救い。
Linux のほうが徹底しているけど Windows も名の知れたものしか残らないわな。

Windows Power Shell も XP ではシステムフォルダに普通にアクセスしやがる。
楽といえば楽だけどチト怖いわ。

つーことで Windows でもやっぱり Python が主になる。
てゆーか Python しか入れてネェじゃん、あんなにバカにしたのに。
せっかくだから 2.6.2 を使って何か作ってみよう。
こんな私だから Python で Opera を弄くって遊ぶコードでも。

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

import sys
import ctypes

SW_HIDE = 0
SW_MAXIMIZE = 3
SW_MINIMIZE = 6

class FindOpera():
    """
        Windows で Opera を弄くる Python スクリプト
    """
    def __init__(self):
        # user32.dll のコネクト
        self.user32 = ctypes.windll.user32
        # Ansi の関数を使うなら Ansi、UNICODE を使うなら u を使う
        #self.hwnd = self.user32.FindWindowA("OpWindow", None)
        self.hwnd = self.user32.FindWindowW(u"OpWindow", None)
        if self.hwnd:
            print(unicode("起動しています", "utf-8").encode("sjis"))
        else:
            print(unicode("見つかりません", "utf-8").encode("sjis"))
            sys.exit()

    def move(self, x, y, width, height):
        # 移動とリサイズ
        self.user32.MoveWindow(self.hwnd, x, y, width, height, True)

    def active(self):
        # Z オーダーの一番上に持って行く
        self.user32.SetForegroundWindow(self.hwnd)

    def set_title(self, title):
        # タイトルバー文字列を変更する
        self.user32.SetWindowTextW(self.hwnd, title)

    def maximize(self):
        # 最大化
        self.user32.ShowWindow(self.hwnd, SW_MAXIMIZE)

    def minimize(self):
        # 最小化
        self.user32.ShowWindow(self.hwnd, SW_MINIMIZE)

if __name__=="__main__":
    opera = FindOpera()
    opera.active()
    #
    # お好きなのを有効にして実行してみてね
    #
    #opera.move(0, 0, 640, 480)
    #opera.set_title(u"おぺらだよーん - Opera")
    #opera.maximize()
    #opera.minimize()

Linux と併用だから UTF-8 にしているけど cp932 で書いたほうが楽だね。
つーか local と内部コードが違う変態 OS はやっぱり面倒だ。

ま、ウインドウのクラス名が解れば何だってコレは可能なんだけどさ。
とりあえず Windows で 2.6 の実験ということで。

メニューのサイズに差がありすぎ

GuestAdditions はなんとかなったので仮想の Windows XP に開発環境を構築。
ということで VisualStudio をインストール、しかし何度やっても失敗する。
どうも環境じゃなくドライブがおかしいっぽい??

なんかやる気失くした、使うかどうかも解らないし。
.NET がやりたくなったら HDD を繋ぎかえて Vista に戻せばいいや。

ということでネタが無いから日記。

20090503

現在丸ごとコードで作成に切り替え中、v0.1.0 という中途半端なバージョンに。

よく考えたら y901x のクラスは dbus.service.Object の継承なんだっけ。
gtk.Window とで多重継承できるのかな?イマイチよく解らないものはやってみるのが早い。
できないみたい…結局 gtk.Window は self.w とすることに。

それと右クリックメニューをこうしたいんだが。

mainmenu

メニューの横分割を GTK+ はサポートしているのかさえ解らない状態。

てゆーか 100% サイズで画像を貼って見比べるとメニューのサイズに差がありすぎ。
これは同じようにするとかなりみったくないぞ。

かといって入れ子にすると使いにくいし上手い方法が思いつかない。
古い Windows だからできた技なんだよなぁこれ、何か技は無いだろうか?

VirtualBox の今後

Ubuntu 9.04 上の VirtualBox ose にとりあえず Windows XP を再投入。
それは普通に終わり、さて GuestAdditions だ。

メニューから普通に実効したが GuestAdditions がマウントできない!
何か変だ、落ちてきた iso をよく見るとたったの 32 bytes だった。
んなわきゃネェ!中身を見るとやっぱり HTML だ、つまりダウンロード失敗。

http://dlc.sun.com/virtualbox/2.1.4/
ココから無理やり落と…せない。

wget http://download.virtualbox.org/virtualbox/2.1.4/VBoxGuestAdditions_2.1.4.iso
も駄目だ、あきらめよう。

追記 @ 2009.05.03 17:45
駄目元で今日 wget したら落ちてきた!昨日がたまたまなのか修正なのかは解らない。
本体からは試していないけど駄目だったら上のコマンドやってちょ。

Sun の配布している通常版 VirtualBox でも落とすか。
…って何?いつからユーザー登録が必要になったの。
多分これが原因で弾かれているんだなと、これじゃ今後も不具合出まくると思う。
そのうち修正されると思うけど今欲しいんだが。

Windows 版なら窓の杜に…いつのまにか Sun から落とせになっている。
それでもこっちと違い GuestAdditions が同梱なだけマシ、最近のは知らないが。
通常版なら Linux 用にも同梱されているのかな?無かったら終わりなんですけど。

やる気をなくした、このままでも遅くて少し不便ながら使えるからいいや。

次は Ubuntu 8.04 だ。
それは普通に終わり、やっぱり画面が 800×600 なので xorg.conf の書き換え…
ってビデオドライバーは…そうかこのまま使うしかないのか。

最後の手段、コイツをダウンロード。
VirtualBox用仮想マシン | Ubuntu Japanese Team

アップデートしたらマウス統合が無効になっちゃった。
まあいいや、Windows XP も同じだし逆に間違えないだろう。

弄くっていると X が落ちまくる、3D で使っているのが悪いのだろうか?
Windows と違って再起動するのは X だけで済むけどやはり ATI はまだ相性が悪いっぽい。
とにかく半日以上使ってやっと仮想環境構築が終わったので前日のコードを試す。

desk_all

おぉ動く動く。
PyGtk のサイトで使えるバージョンを確認しても実際に試さないと怖いのよ。

しかし GuestAdditions がどうにかならないと他の OS が入れられないぞと。
Linux は 800×600 以上にならない、VMware なら Ubuntu はドライバー標準装備なんけど。
別の仮想環境を試…ビデオドライバーがありそうなのはこの2つしか無いので選ぶ余地は無いか。
なんか他にイイ方法は無いものか、パソコンの台数を増やしてももったいないしなぁ。

それよりあーあ、仮想の Windows から UnitMovie をリモートして動画結合ができないや。

GtkUIManager と GtkActionGroup

さーて、今日も Python だ。
ところで先月のウチへの検索ワードを晒す。

acc1

Python や PyGtk 関係はいずこ、、、、、orz

SEO もクソもあったもんじゃねぇ、でも続ける。

つーことで gEdit も内部で使っている GtkUIManager とやらを使ってみたい。
内部ではどう使われているかなんか知らないよ、当然実装方法なんか解らない。
日本語で PyGtk を探しても見つかるはずがないので最初から米国の google で検索!

私自身がこうだもの、そりゃ SEO にならない、、、、orz

PyGTK 2.0 Tutorial

公式のの「16.7. The UIManager」が普通に一番解りやすい。
つまり gtk.UIManager のインスタンスに読み込ませるとオブジェクトが作られる。
ソレを get_widget メソッドで取り出してパッキングする。
という流れでいいみたい。

ついでに GtkActionGroup の使い方も解りやすく書いてくれている。
XML で action 属性を同じ str にしたものは同じ動作をするわけだ。

そういえば Delphi にも TActionList なんてのがあった。
というか Palepoli v2 で使っていた、便利なんだよね。
メニューと右クリックメニューとボタンの動作指定やハンドラが共用できて。

倍率指定のラジオボタンをメインメニューと右クリックメニューで同じにする必要がある。
ハンドラは同じ名前を指定すればいいだけだがラジオの位置は別々に変更を迫られる。
だけどこれを使えば解決だ、位置も XML で指定できるから同じにする必要はない。

早速書いてみようと思ったけどココ何か説明がたりない。

gtk.ActionGroup

add_radio_actions には GtkRadioActionEntry を入れなきゃいけないんだが。
詳しくは Devhelp を見てね、つーことで昨日のコードに書きたし。

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

ui_str = """<ui>
    <menubar name="MenuBar">
        <menu action="File">
            <menuitem action="quit"/>
        </menu>
        <menu action="View">
            <menuitem action="x00"/>
            <menuitem action="x10"/>
            <menuitem action="x20"/>
            <menuitem action="x30"/>
            <menuitem action="x05"/>
            <menuitem action="x15"/>
            <menuitem action="x25"/>
            <menuitem action="xs1"/>
            <menuitem action="xs2"/>
            <menuitem action="xs3"/>
        </menu>
    </menubar>
    <popup>
        <menuitem action="x00"/>
        <menuitem action="x10"/>
        <menuitem action="x20"/>
        <menuitem action="x30"/>
        <menuitem action="x05"/>
        <menuitem action="x15"/>
        <menuitem action="x25"/>
        <menuitem action="xs1"/>
        <menuitem action="xs2"/>
        <menuitem action="xs3"/>
        <separator/>
        <menuitem action="quit"/>
    </popup>
</ui>"""

import gtk
import common

class TestWindow(gtk.Window):
    def __init__(self):
        # 継承のお約束
        gtk.Window.__init__(self)
        #
        # メニューを作る
        #
        # まず GtkUIManager 作成
        uimanager = gtk.UIManager()
        # GtkAccelGroup を得る
        accelgroup = uimanager.get_accel_group()
        self.add_accel_group(accelgroup)
        # GtkActionGroup 作成
        actiongroup = gtk.ActionGroup("sasakimamenu")
        # GtkActionEntry を作成して突っ込む
        # name, stock_id, label, accelerator, tooltip, callback
        actions0 = [("quit", gtk.STOCK_QUIT, "終了(_Q)", "<Control>Q", "さいなら", self.on_quit),
                    ("File", None, "ファイル(_F)"),
                    ("View", None, "表示(_V)")]
                    #("Popup", None, "")]
        actiongroup.add_actions(actions0)
        # GtkRadioActionEntry の List を作成
        # name, stock_id, label, accelerator, tooltip, value
        actions1 = [("x00", None, "ウインドサイズ", "0", "ウインドサイズ", 0),
                    ("x10", None, "x1.0", "1", "x1.0", 1),
                    ("x20", None, "x2.0", "2", "x2.0", 2),
                    ("x30", None, "x3.0", "3", "x3.0", 3),
                    ("x05", None, "x0.5", "4", "x0.5", 4),
                    ("x15", None, "x1.5", "5", "x1.5", 5),
                    ("x25", None, "x2.5", "6", "x2.5", 6),
                    ("xs1", None, "set1", "7", "set1", 7),
                    ("xs2", None, "set2", "8", "set1", 8),
                    ("xs3", None, "set3", "9", "set1", 9) ]
        # GtkRadioAction を突っ込む
        # entries, value=0, on_change=None, user_data=None
        actiongroup.add_radio_actions(actions1, 0, self.on_size_change)
        #
        uimanager.insert_action_group(actiongroup, 0)
        uimanager.add_ui_from_string(ui_str)
        # Popup Menu を得る
        self.popup_menu = uimanager.get_widget('/popup')
        # セレクタの List を作っておく
        self.size_str = ["win","x1.0","x2.0","x3.0","x0.5","x1.5","x2.5","set1","set2","set3"]
        # おしまい
        #
        # ステータスバーを作る
        self.sb = common.CStatusBar(2, self)
        self.sb.label[0].set_text("こんどは")
        self.sb.label[1].set_text("menu を作ったよ")
        vb = gtk.VBox()
        # 最初にメニューを突っ込もうね
        menubar = uimanager.get_widget("/MenuBar")
        vb.pack_start(menubar, False)
        da = gtk.DrawingArea()
        vb.pack_start(da)
        vb.pack_start(self.sb, False, False, 0)
        self.add(vb)
        self.connect("delete-event", self.on_quit)
        # GDK イベントの有効化を行っておく
        da.set_events(gtk.gdk.BUTTON_PRESS_MASK)
        da.connect("button_press_event", self.on_button_down)
        self.resize(320, 240)
        self.show_all()
    
    def on_size_change(self, action, current):
        # ステータスバーにサイズの表示
        self.sb.label[1].set_text(self.size_str[action.get_current_value()])
    
    def on_quit(self, widget, event=None):
        # bye
        gtk.main_quit()
        return True
    
    def on_button_down(self, widget, event):
        # 右クリで PopupMenu
        if event.button == 3:
            self.popup_menu.popup(None, None, None, event.button, event.time)

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

おぉメインメニューも右クリも完全に同じ動作だ、コイツは楽ちん。
実は右クリックメニューをどうするかで悩んでいたけどコレで決まりだ。
ちなみに Y901 はメインと右クリックで同じメニューを出していたので必要無かった。

とりあえず Ubuntu 9.04 ならこのコードで動く。
以前のバージョンは…確認用にそろそろ旧バージョンを VirtualBox に入れなきゃ。