pygtkで遊ぼう(8) gtk.Menuを使ったコンテキストメニュー

今回はgtk.Menuを使って、コンテキストメニューを表示させてみました。
まずは実行結果から。

ウインドウ上のフレーム(gtk.Frame)上で右クリックすると、スクリーンショットのような感じでコンテキストメニューが表示されます。

また、コンテキストメニューを選択すると、print文で選択されたアイテム名を出力します。

ソースコードは以下のようになっています。

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

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

class TestWindow:
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title('TestWindow')
        self.window.set_border_width(2)
        self.window.set_size_request(200, 100)
        self.window.connect('delete_event',
                            self.on_quit)

        ebox = gtk.EventBox()
        ebox.connect('button_press_event',
                     self.on_button_press_event)
        ebox.add(gtk.Frame('ContextMenu Frame'))
        self.window.add(ebox)

        # コンテキストメニューの構築
        self.contextMenu = gtk.Menu()
        for name in [ 'item%d' % i for i in range(5)]:
            item = gtk.MenuItem(name)
            item.connect('activate', self.on_activate_context_menu)
            self.contextMenu.append(item)
        self.contextMenu.show_all()

        # ウインドウの表示
        self.window.show_all()
        
        gtk.main()

    def on_quit(self, widget, event=None, data=None):
        '''
        終了時に実行する処理
        '''
        print '-- quit --'
        gtk.main_quit()
        return False

    def on_button_press_event(self, widget, event=None):
        '''
        マウスがクリックされた場合に実行する処理
        '''
        print event.button
        # 右クリックでなければ処理を中止
        if event.button != 3:
            return
        
        # コンテキストメニューの表示
        self.contextMenu.popup(None,
                               None,
                               None,
                               event.button,
                               event.time)

    def on_activate_context_menu(self, menuItem):
        '''
        コンテキストメニューが選択された場合の処理
        '''
        print menuItem.get_child().get_text()
        
        
#
#
if __name__ == '__main__':
    wind = TestWindow()
    

上記のソース中の赤文字で書かれている部分がコンテキストメニューに関係する部分です。

        # コンテキストメニューの構築
        self.contextMenu = gtk.Menu()
        for name in [ 'item%d' % i for i in range(5)]:
            item = gtk.MenuItem(name)
            item.connect('activate', self.on_activate_context_menu)
            self.contextMenu.append(item)
        self.contextMenu.show_all()

上の部分では、ループで5つのコンテキストメニュー項目(gtk.MenuItem)を作成して、gtk.Menuに追加しています。

そして、マウスクリック時のコールバック関数中では、右クリックかどうかを判定した後、

        # コンテキストメニューの表示
        self.contextMenu.popup(None,
                               None,
                               None,
                               event.button,
                               event.time)

コンテキストメニューを表示させています。
pygtkのリファレンスにも書かれていますが、コンテキストメニューを表示させる場合には、
一般的にpopupの最初の3つの引数はNoneを指定します。

今回勉強になったこと

コンテキストメニューが選択されたときの処理で以下のようにしています。

    def on_activate_context_menu(self, menuItem):
        '''
        コンテキストメニューが選択された場合の処理
        '''
        print menuItem.get_child().get_text()

これはコールバックとして渡されてくるmenuItemのget_child()を調べて見たところ、
gtk.AccelLabel(gtk.Labelのサブクラス)だったので、「お、get_text()が使えるね!」となったわけです。(笑

いや〜今日も勉強になりました。

つづく。