pygtkで遊ぼう(6) メニュー編

今日はpygtkアプリケーションにメニューバーを追加する方法です。
いきなりですが、ソースコードは以下のようになっています。
メニューバーからアプリケーションを終了するようにはできていませんが、そのあたりはご了承ください。

# -*- coding: utf-8 -*-

import sys
import pygtk

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

#
#
class simpleWindow:
    '''
    テスト用ウインドウ
    '''

    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()

        menubar = self.get_main_menu()
        vbox.pack_start(menubar, False, False, 0)

        layout = gtk.Layout()
        vbox.pack_start(layout)
        
        self.window.add(vbox)
        self.window.show_all()
        
        gtk.main()

    def get_main_menu(self):
        '''
        メインメニュー構築処理
        '''
        ## メニューバーの定義
        mainMenu = '''
        
            
                
                    
                    
                

                
                    
                    
                

                
                    
                    
                
            
        
        '''

        # UIManagerインスタンスの再生
        uimgr = gtk.UIManager()
        
        # アクセラレータグループをウインドウに追加
        acclgrp = uimgr.get_accel_group()
        self.window.add_accel_group(acclgrp)

        # アクショングループの作成
        actgrpBase = gtk.ActionGroup('MenuActionBase')
        actgrpBase.add_actions([('Normal Menu', None, '_Normal Menu'),
                                ('Toggle Menu', None, '_Toggle Menu'),
                                ('Radio Menu', None, '_Radio Menu')])

        uimgr.insert_action_group(actgrpBase, 0)

        # ノーマルメニューアクションの登録
        actgrpBase.add_actions([('normal item 1', None,
                                 'item _1', None,
                                 'sample item for normal menu action',
                                 self.on_normal_item1),

                                ('normal item 2', None,
                                 'item _2', None,
                                 'sample item for normal menu action',
                                 self.on_normal_item2)])
                                
        # トグルメニューアクションの登録
        actgrpBase.add_toggle_actions([('toggle item 1', None,
                                        'item _1', None,
                                        'sample item for normal menu action',
                                        self.on_toggle_item1,
                                        True),

                                       ('toggle item 2', None,
                                        'item _2', None,
                                        'sample item for normal menu action',
                                        self.on_toggle_item2,
                                        True)])

        # Modeメニューアクションの登録
        actgrpBase.add_radio_actions([('radio item 1', None,
                                       'item _1', None,
                                       'sample item for normal menu action',
                                       0),

                                      ('radio item 2', None,
                                       'item _2', None,
                                       'sample item for normal menu action',
                                       1)],
                                     0,
                                     self.on_radio_menu_changed)
        
        uimgr.add_ui_from_string(mainMenu)
        
        return uimgr.get_widget('/MenuBar')        

    def on_normal_item1(self, widget, event=None, data=None):
        '''
        normal item 1が選択された場合の処理
        '''
        print 'normal item 1'

    def on_normal_item2(self, widget, event=None, data=None):
        '''
        normal item 2が選択された場合の処理
        '''
        print 'normal item 2'

    def on_toggle_item1(self, action, data=None):
        '''
        toggle item 1が選択された場合の処理
        '''
        print 'toggle item 1 is %s' % action.get_active()
        print data

    def on_toggle_item2(self, action, data=None):
        '''
        toggle item 2が選択された場合の処理
        '''
        print 'toggle item 2 is %s' % action.get_active()
        print data

    def on_radio_menu_changed(self, action, current, data=None):
        '''
        Radioメニューの選択が変更された場合の処理
        '''
        print 'radio item %d selected' % action.get_current_value()
    
    def on_quit(self, widget, event=None, data=None):
        print '-- quit --'
        gtk.main_quit()
        return False


#
#
def main():
    wind = simpleWindow()
    

#
#
if __name__ == '__main__':
    main()

上記のソースを実行すると、こんなウインドウが表示されます。

今回は3種類のメニュー構成にしてみました。
(1) 一般的なメニューアイテムを持つメニュー
(2) トグルするメニューアイテムを持つメニュー
(3) ラジオボタンのように排他的に選択できるメニューアイテムを持つメニュー

ソースコード中でメニューバーを作成している関数は、

def get_main_menu(self):

です。

通常のメニュー項目の追加

        # ノーマルメニューアクションの登録
        actgrpBase.add_actions([('normal item 1', None,
                                 'item _1', None,
                                 'sample item for normal menu action',
                                 self.on_normal_item1),

                                ('normal item 2', None,
                                 'item _2', None,
                                 'sample item for normal menu action',
                                 self.on_normal_item2)])

add_actions()の引数にはタプルまたはリストを指定します。
上記の場合には、2つのタプルを要素に持つリストです。
それぞれのタプルがメニュー項目についての設定です。

タプルには6つの項目があり、それらの意味は
1.メニュー項目名
2.ストックID
3.メニュー項目ラベル
4.アクセラレータ
5.メニュー項目に対するツールチップ文字列
6.メニュー項目が選択された場合に呼び出されるコールバック

トグルするメニュー項目の追加

        actgrpBase.add_toggle_actions([('toggle item 1', None,
                                        'item _1', None,
                                        'sample item for normal menu action',
                                        self.on_toggle_item1,
                                        True),

                                       ('toggle item 2', None,
                                        'item _2', None,
                                        'sample item for normal menu action',
                                        self.on_toggle_item2,
                                        True)])

add_toggle_actions()の引数もタプルまたはリストを指定します。
上記の場合には、2つのタプルを要素に持つリストです。
それぞれのタプルがメニュー項目についての設定です。

タプルには7つの項目があり、それらの意味は
1.メニュー項目名
2.ストックID
3.メニュー項目ラベル
4.アクセラレータ
5.メニュー項目に対するツールチップ文字列
6.メニュー項目が選択された場合に呼び出されるコールバック
7.トグル状態の初期値(Trueで選択状態、Falseで非選択状態)

排他的なメニュー項目の追加

        # Modeメニューアクションの登録
        actgrpBase.add_radio_actions([('radio item 1', None,
                                       'item _1', None,
                                       'sample item for normal menu action',
                                       0),

                                      ('radio item 2', None,
                                       'item _2', None,
                                       'sample item for normal menu action',
                                       1)],
                                     0,
                                     self.on_radio_menu_changed)

add_radio_actions()の引数もタプルまたはリストを指定しますが、リストに
加え、デフォルトで選択される要素の識別番号、項目の選択状態が変更された場合に
呼び出されるコールバック関数も指定します。

上記の場合には、2つのタプルを要素に持つリストです。
それぞれのタプルがメニュー項目についての設定です。

タプルには6つの項目があり、それらの意味は
1.メニュー項目名
2.ストックID
3.メニュー項目ラベル
4.アクセラレータ
5.メニュー項目に対するツールチップ文字列
6.メニュー項目が選択された場合の識別番号

今回はかなり駆け足での説明なので不明な箇所はpygtkのリファレンスを参照してください。

つづく。