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 は親から使うのだった、ちょっと紛らわしいよねココ。