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

class 分け

Y901x は Glade を使って GtkBuilder 形式に変更する。
と書いたけど何か気に入らない、何かを忘れているような感じ。

Glade 等の GUI 作成ツールを使うと全部 GTK+ 部品のベタ打ちになる。

自分で都合がいいよう個別パーツに分けて作ったほうが良くないか。
現状では表示非表示切り替えやリストのリサイズ等で無駄を感じるんだが。
それよりも Glade のバージョンにまで左右されるのでは今後更に困るかも。

Delphi 屋だった頃も徐々に自作でクラスやコンポーネントを作るようになっていった。
今はまだいいがもう少しサイズが大きくなると破綻しそうだし、よしやってみるか。

ステータスバーを自作する

とりあえずこの部分をまとめて class にしてみよう。

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

import os
import gtk

class CStatusBar(gtk.VBox):
    """
        Instead GtkStatusbar
    """
    def __init__(self, num, window):
        """
            @param num: Total of Label
              statusbar.label[0].set_text("aiueo")
            @param window: Toplevel Window
              Use "begin_resize_drag" Event
        """
        self._win = window
        # public menber
        self.label = []
        # init Original inheritance
        gtk.VBox.__init__(self)
        # GtkLabel and GtkVSeparator
        hb = gtk.HBox()
        for i in range(num):
            l1 = gtk.Label()
            s1 = gtk.VSeparator()
            # HBox insert param (child, expand=True, fill=True, padding=0)
            hb.pack_start(l1, False, False, 10)
            hb.pack_start(s1, False, False, 0)
            self.label.append(l1)
        
        # Dummy
        ld = gtk.Label()
        hb.pack_start(ld)
        # Grip
        grip = gtk.EventBox()
        self._im = gtk.Image()
        path = os.path.dirname( __file__ ) + "/img/grip.xpm"
        self._im.set_from_file(path)
        grip.add(self._im)
        hb.pack_end(grip, False, False, 0)
        # Grip connect
        self._first_show = False
        grip.connect("button_press_event", self.on_resize)
        grip.connect("expose-event", self.on_expose)
        # pack
        s0 = gtk.HSeparator()
        self.pack_start(s0, False, False, 0)
        self.pack_start(hb, False, False, 0)
        self.show_all()
    
    def on_resize(self, widget, event):
        # begin resize @ Toplevel Window
        self._win.begin_resize_drag(gtk.gdk.WINDOW_EDGE_SOUTH_EAST,
                                    event.button,
                                    int(event.x_root),
                                    int(event.y_root),
                                    event.time)
    
    def on_expose(self, widget, event):
        # Cursor Change
        if not self._first_show:
            cur_grip = gtk.gdk.Cursor(gtk.gdk.BOTTOM_RIGHT_CORNER)
            self._im.window.set_cursor(cur_grip)
            self._first_show = True

DocString を英語にしているのは単にカッチョイイと思ったから。
間違えている可能性大だからあんまり気にしないでチョ。
これを common.py という名前で保存して以下のコードを。

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

import gtk
import common

class TestWindow(gtk.Window):
    def __init__(self):
        # 継承のお約束
        gtk.Window.__init__(self)
        # 使ってみる
        sb = common.CStatusBar(2, self)
        sb.label[0].set_text("自作")
        sb.label[1].set_text("statusbar クラスを作ったよ")
        # pack
        tv = gtk.TextView()
        vb = gtk.VBox()
        vb.pack_start(tv)
        vb.pack_start(sb, False, False, 0)
        self.add(vb)
        self.connect("delete-event", gtk.main_quit)
        self.resize(320, 240)
        self.show_all()

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

statusbar

んーこれでまったく同じように使えるようになりました。
GtkLabel のリストである label メンバ以外にアクセスしないようにした。
結果的に本体でやることは作成とラベルへの文字列挿入だけになる。
コードも XML で作るよりスッゲェ短くなる、他への使い回しもこれなら簡単。

なんだよ、コードで作るって良いことだらけだ。
いや、Glade があったおかげで私は GTK+ が使えるようになった。
それは間違いない、だけどそろそろ継承をやる時期なのかなと思ったので。

しかしコードで部品のパッキングをやるのは久々でやりかたを忘れて困ったわ。
expand や fill は親から使うのだった、ちょっと紛らわしいよねココ。

Y901x 0.0.6

Y901x v0.0.6 に更新

* フルスクリーンをとりあえず可能にした
   Z キーと W クリックで切り替え
   現在フルスクリーンでシークバーは出ませんのであしからず
* 多重起動防止でしばらくプロセスが残ってしまうのをなんとかした
* シークバーからマウスを離すとフォーカスを他へ移すようにした
* has_tooltip, tooltip_markup プロパティの削除
* 諸事情でメニューからアクセラレータキーの表示が消えています、ごめん
* 次回より GtkBuilder 形式及び Ubuntu 9.04 以降専用になる予定

はぁ、メニューからアクセラレータのキー文字を消すはめになった。
操作性が少々特殊な部類のアプリなのに自殺行為だ。

ぶっちゃけ Totem とかに操作性を合わせるほうが圧倒的に楽なんだが…
しかしこのポリシーを曲げたら私のアプリではないし作る意味すら無い…
とにかく出すと書いたからムリムリにつじつまだけ合わせた。

GtkBuilder 形式に変更すればもうちょっとマシな方法があるかな?
色々と面倒くさいのでさっさと GtkBuilder 形式に書き換えようと思っていたんだけど。

menu216

9.04 の Gnome は 2.26 だけど Gtk+ のバージョンは 2.16 なので勘違いしないでね。
Ubuntu 8.10 の Gtk+ は 2.15 だ、何も考えずに利用するわけにはいかない。
自分が使うことだけを考えるならどうでもいいことなんですけど、どうしよう…

Fedora 11 はまだ出ていないし事実上現在は Ubuntu 9.04 専用になってしまう。
なんて言っていてもこの業界ではすぐに陳腐化してしまうのですけど。
「最新環境で作っているコード」のほうがイイかもしれない、ネタも作りやすい。

こうなったら Mono で、そのほうがウケは悪いが Python よりアクセスは稼げる。
って、標準の中に GStreamer# が見当たらないや、ヤメとこう。

ところで気分を変えるために TomBoy を使ってみようと考えた。
Windows や Mac 版もあるみたいだし便利かも、と思ったんですけど…

Tomboy/Installing/Windows – GNOME Live!

Tomboy/Installing/Mac – GNOME Live!

Windows に GtkSharp を入れてくれかよぉ!
Mac に至っては当然 Mono 自体のインストールが必要になる。
VB ランタイムの頃を思い出した、だから依存はイヤなんだ。

Ubuntu 9.04 そのよん

さて Ubuntu 9.04 をインストールいたしました、4回め。

こんなブログを運営している人はスナップショットをよく使うと思います。
それで私はこんな覚書を作ったのですが

スクリーンショットを取る

9.04 の標準「スクリーンショットの取得」は神レベル。

screen

あると便利なマウスドラッグでの指定範囲取得が可能になりました。
それだけなら Windows Vista 付属の Snipping Tool と変わらないように思えます。
しかしコレはボタンを押した時点で起動前にアクティブだったウインドウが再アクティブになる。

Snipping Tool 最大の欠点はウインドウが非アクティブ状態でしかショットできなかったこと。
つまりタイトルバーが薄い状態です、濃い状態で画像化したい場合って結構多い。
しかたがないので全画面をスナップしてペイントに張り付けて保存してソレを開いてスナップ…
なんて冗談みたいな苦労をやっていたのは私だけじゃないと思いますけど。

コレはアクティブ状態で選択範囲が普通に取得できる。
あぁこれでもう枠付けや加工をする時意外は Gimp を使わなくてもいいんだ、本気で嬉しい。

toolbar

こうしておいて Snipping Tool のように使おうと思ったけどオプションが無かった…
それだけが残念、まぁちょっぴり手順が増えるだけだしこれでイイかなと。

で、私は Y901x という需要の無さそうな Python 製動画プレイヤーを作っているのだが。

…この Glade で以前の glade ファイルを編集できねぇ!!!!!

上書き保存したら XML が少々違うタグ付けになって読み込めない。
手順が悪いのかな?と思って色々試したけどダメ、上手くいった人いたら教えて。
しかたがないから手書きで XML を編集するはめに、簡便してよ。

とりあえず明日あたりに次版を出した時点で GtkBuilder 形式に変更しよう。
もう LibGlade 形式は消えゆく運命なのかな。

以下 Python 覚書。

PyGTK FAQ Entry @ How can I focus an external window?

これを使って URI を送ったらウインドをアクティブにしようと思っていたんだけど…
gtk.get_current_event_time() がどうしてもゼロになってしまい上手くいかない。
Gtk アプリは URI を渡されてもアクティブ化しないのが普通なのでこのままいくか。
どうもそういう細かい違いが気になるんだよなぁ、WIndows で長くやっていると。

とりあえずフルスクリーンが上手くいきそうだから付けてみる。
ところで GtkMenubar は非表示にするとアクセラレータが効かなくなっちゃうのね…
全部 GtkAccelGroup 利用に書き換えだ、覚書はどうしよう…

ところで今まで多重起動防止でしばらく次タスクが出てしまう件は回避方法を見つけた。

gtk.gdk.notify_startup_complete()

を DBus 経由で URI を渡した後に呼び出せば綺麗に死んでくれる。
コレを呼び出す前にキュー(でいいのかな?)を空にしておいて。

while gtk.events_pending():
    gtk.main_iteration()

つまり簡単に言えば Delphi でいう Application.ProcessMessage() である。
余計に解り憎いわ!いや、私にはこれが一番解りやすいんですけど。
ちょっと Windows が長かったので Linux らしくない説明が多いのはご了承。

Ubuntu 9.04 そのさん

さて Ubuntu 9.04 をインストールいたしました、更に続き。

何か忘れているなぁ?と思いながら Y901x の開発再開をしようとする。

…Glade をインストールしてねぇ!

ということで毎度のように追加と削除から。
あれ?こんなにサイズがデカかったかな…落とすのにえらく時間が掛かるような。
とにかくインストール完了した時点でバージョン確認のために起動。

ちょー!メチャメチャ変わっている!!!

glade_a

v3.4.5 → v3.6.1 なんだがマイナーチェンジに見えないわ。
一応今までに作った y901window.glade は開けるが古さを感じてしまった。
GtkBuilder と Libglade が選択できるのは解っていたが進化が早すぎ、、、、、

GtkBuilder 形式って GtkListStore や GtkTextBuffer も含められるのか。
View と Data をまとめようってこと?それ WPF と真逆だと思うんですけど。
なんかいっぱいウイジェットが増えているし、ガンマ曲線とかって何よ?

他やれることが至れり尽くせりに、旧バージョンはいったいなんだったの。
「展張」とか意味不明すぎる日本語訳はそのままだけど。

せっかくだから UI Mnager を使いたいが使い方がイマイチ解らない。
ググるも見当たらず、又自分で弄くり回して覚書を作るしかないか。
あぁせっかく書いた PyGtk+Glade 覚書は早くも過去の遺物になった。

同時に入る DevHelp もボリュームたっぷりに進化。
Evolution や Totem の Core API まで解説とは…サイズがデカいわけだ。
そうそう、何故か巨大だった文字サイズは普通になった。

devhelp1

Glade 関連だけで長くなりそうなので以後まとめページを作るとして。
開発繋がりで MonoDevelop を少し試してみます。

前回書いたとおり 9.04 では MonoDevelop のみインストールすれば全部揃う。
早速 C# 3.0 仕様に対応しているか簡単に試してみます。

using System;

namespace hello
{
    class Cls
    {
        public string s{get; set;}
        public void write(string t)
        {
            Console.WriteLine(t + s);
        }
    }

    delegate string Delgt(string t, string u);

    /// <summary>
    /// エントリポイント
    /// </summary>
    class MainClass
    {
        private static void DTest(string t, string u, Delgt d)
        {
            Console.WriteLine( d(t, u) );
        }

        public static void Main(string[] args)
        {
            // var が使えるか test
            var s = "あいうえお";
            Console.WriteLine("{0}_かきくけこ", s);

            // 省略プロパティ test
            var ss = new Cls();
            ss.s = "たちつてと";
            ss.write("さしすせそ_");

            // 匿名メソッド test
            DTest("匿名メソッド", "の出力", delegate(string t, string u) {return t+u;});

            // ラムダ式 test
            DTest("の出力", "ラムダ式", (t, u) => u+t);
        }
    }
}

mono_hello

おぉ動く動く。
他人が読みにくいコードを書いて悦に浸りたいなら C# は最強だね。

MonoDevelop の全置換って Tab の正規表現 \t が使えないんですけどぉ、、、、、
gEdit で置換しました。

ん?標準で作成するソースに utf-8 の BOM が付かなくなった。
IDE からソース追加すると元々付かなかったんだが、無しに統一かな。
MSBuild 形式になった sln ファイルには付いている。

bom

Visual Studio は全ファイルに BOM を付けているはずなんだけーが。
てか sln だけ改行が CRLF だよ、ややこしいったらありゃしない。
BOM という概念は撤廃してくれよ、必要なのはもはや MS 関連のみなんだから。

コード保管は随分賢くなったなぁ、リファクタリングはさすがにまだ無いか。
これも長くなりそうなので以後まとめページを作る。

今回は「追加と削除」から手に入る最新開発環境の簡単な紹介でした。

Ubuntu 9.04 そのに

さて Ubuntu 9.04 をインストールいたしました、続き。

ちょー!
Totem に flv や wmv を放り込んで codec を入れていたんだが…
得に怪しいこともしていないのに RealMedia がサムネイルされていた…
当然 GStreamer から普通に RealMedia が再生できるんですけど…
ライセンスはいいのだろうか?某社はもう諦めたのだろうか。

まあソレはソレとして。
コレがなくては不便なので入れるアプリの覚書。

Opera ブラウザ
VirtualBox 仮想マシン
Sylpheed メーラー
Hex Editor バイナリエディタ
KeePassX パスワード管理
Apache2、PHP、MySql ローカルサーバー
MonoDevelop C# と C/C++ 開発手抜き用
flashplugin-installer、lha-sjis 日本語環境セットアップヘルパから
gcc は後述
自作アプリと自作 gEdit プラグインと自作シェルスクリプトもろもろ。

後は最初から入っているアプリで全部まかなえる。
アプリやサイトを作って遊ぶか YouTube かしかやっていないような…
パーソナルユースなんて人それぞれだい。

以前は nautilus-gksu とかがありがたかったけど慣れると端末のほうが融通が効く。
つかクソ長いパスでも端末に sudo gedit とか打ってファイルをドロップすればいいんだし。
mono アプリも mono って打ってドロップ、覚えておくと便利だよ。
ま、今は Tab キー使うけど。

気がついたが Gtk アプリの GtkHScale とかにフォーカスが移ると網掛けが入る。
ATI だったので 8.10 まで 2D で使っていたのだが前からこうなのかな?
Totem のシークバーとかでウザいんだが、当然 Y901x もそうなるが。

前回書き忘れたが ATI でも 3D で動画がチカチカしなくなっているよ。
逆に本家ドライバーを入れるとどうなるか解らない。

あれ? build-essential は入れていないのに gcc や libc6 が既に入っているぞ
Ubuntu のポリシーからして最初から入っているなんて思えないんだが。

Ubuntu — Details of package monodevelop in jaunty

MonoDevelop を導入した時に同梱されていたようで。
前のパッケージは C# コンパイラさえ別配布だったのに親切になったものだ。
gmcs とかは書いていないけど入っていた。

それよりやっぱり gEdit がおかしい。
smart_home_end を BEFORE にしても AFTER のままな動きになったり。
その場はよいのだがログアウトするとダメになったり、よーわからん。
スニペットの $0 指定が効かないのは $1 に書き換えればとりあえず動く。

snip

これじゃ標準のも書き換えせにゃならんわ、まいった。