pygtkで遊ぼう(7) gtk.Statusbar編

今日は覚え書きをかねて、gtk.Statusbarについてです。
ステータスバーといえば、ウインドウの下の方にくっついていることが多いおなじみのUIパーツですね。

実際にgtk.Statusbarを使ってみると、ステータスバーを分割するAPIがないことに気づきました。
複数の種類の情報を1本のステータスバーに表示しようとしたときにこれでは不便ですよね。
複数の情報を1つの文字列にして、ステータスバーに設定してもいいのですが、それぞれの情報の文字列の長さが変わると、表示位置が動いてしまうので、煩わしいです。

そこで、今回は、ステータスバーの分割を指定できるようにカスタマイズしてみました。
イメージとしては、こんな感じになります。

ソースコードはこんな感じです。

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

import sys
import pygtk

if sys.platform != 'win32':
    pygtk.require('2.0')
import gtk

#
#
class SeparatedStatusBar(gtk.Statusbar):
    def __init__(self, number):
        '''
        初期化
        '''
        gtk.Statusbar.__init__(self)

        self.statusList = []

        sbDict = {'id': 0, 'bar': self}
        self.statusList.append(sbDict)

        if number > 1:
            for i in range(number - 1):
                sb = gtk.Statusbar()
                sb.set_has_resize_grip(False)
                self.pack_start(sb)

                sbDict = {'id': 0, 'bar': sb}
                self.statusList.append(sbDict)

    def push_at(self, idx, text):
        if idx < 0 or idx >= len(self.statusList):
            return

        info = self.statusList[idx]
        info['id'] = info['bar'].push(info['id'], text)

class TestWindow:
    ##
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_border_width(2)
        self.window.set_size_request(400, 300)
        self.window.connect('delete_event', self.on_quit)
        
        vbox = gtk.VBox()

        evtBox = gtk.EventBox()
        vbox.pack_start(evtBox)

        # 今回作成したステータスバーをウインドウに配置
        self.statusBar = SeparatedStatusBar(4)
        vbox.pack_start(self.statusBar, False, False, 2)

        # 適当な文字列を設定してみる
        for i in range(4):
            self.statusBar.push_at(i, 'No_%d' % i)

        self.window.add(vbox)
        self.window.show_all()
        
        gtk.main()

    ##
    def on_quit(self, widget, event=None, data=None):
        print '-- quit --'
        gtk.main_quit()
        return False
        
if __name__ == '__main__':
    wind = TestWindow()

上記のソースのうち、SeparatedStatusBarクラスが今回のテーマとなっている「分割可能なステータスバー」です。
と、いっても何も複雑なことはせずに実現できました。

SeparatedStatusBarクラスは、gtk.Statusbarのサブクラスとして作成しています。
コンストラクタ中では、指定された数 - 1個のStatusbarを作成し、pack_start()で自分(gtk.Statusbar)の上に配置
しているだけです。

gtk.Statusbarはgtk.HBoxのサブクラスなので、pack_start()やpack_end()などで自分の上に複数のウィジェット
配置できることを利用しました。

SeparatedStatusBarクラスにはpush_at()というメソッドを用意しました。
このメソッドは、gtk.Statusbarのpush()と同じ働きをします。ただ、分割したうちのどこに文字列を設定するのかを指定できるようにしました。

今回作成したクラスよりももっといい方法があるかもしれませんが、今のところこのくらいしか思いつきませんでした(笑