L'Isola di Niente
L'Isola di Niente » PyGObject Tips » メニュー

メニュー

GNOME 標準アプリからはメニューバー、ツールバーは無くなりました。
現状はまだ非推奨になっていませんが時間の問題だと思う。

今後はアプリケーションメニュー、又は GtkMenuButton を使いましょう。
というか、もうタッチパネルは無視できないのでコチラしか選べない。

GtkMenuButton

GtkMenuButton は Nautilus 3.6 から採用されているボタン式メニュー。
作成するとデフォルトは矢印表示のボタンになります。
メニューにするには下記のように GtkImage を貼り付ける。
#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

class GearsMenuWin(Gtk.Window):
    """
        GtkMenuBar Sample
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        #
        # AccelGroup
        accelgroup = Gtk.AccelGroup.new()
        self.add_accel_group(accelgroup)
        # MenuIten
        item_open = Gtk.MenuItem.new_with_mnemonic("_Open")
        item_open.connect("activate", self.on_open)
        item_open.show()
        item_open.add_accelerator("activate", accelgroup, Gdk.KEY_o,
                Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
        item_quit = Gtk.MenuItem.new_with_mnemonic("_Quit")
        item_quit.connect("activate", self.on_quit)
        item_quit.show()
        item_quit.add_accelerator("activate", accelgroup, Gdk.KEY_q,
                Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
        # Menu
        menu = Gtk.Menu.new()
        menu.append(item_open)
        menu.append(item_quit)
        menu.props.halign = Gtk.Align.CENTER
        # GtkMenuButton
        menubutton = Gtk.MenuButton.new()
        menubutton.set_popup(menu)
        # F10 キーでドロップ処理
        menubutton.add_accelerator("clicked", accelgroup, Gdk.KEY_F10,
                0, Gtk.AccelFlags.VISIBLE)
        # 矢印アイコンのまま使うならこれで向きを変更できる
        #menubutton.set_direction(Gtk.ArrowType.UP)
        # 三本線の svg 画像を貼り付ける、GNOME 3.14 から
        image = Gtk.Image()
        # GTK+ 3.12 以前は以下のギヤアイコン
        #image.set_from_icon_name("emblem-system-symbolic", Gtk.IconSize.MENU)
        image.set_from_icon_name("open-menu-symbolic", Gtk.IconSize.MENU)
        menubutton.set_image(image)
        # ヘッダーバーに置く
        hbar = Gtk.HeaderBar()
        hbar.pack_end(menubutton)
        hbar.set_show_close_button(True)
        # self
        self.set_titlebar(hbar)
        self.connect("delete-event", self.on_quit)
        self.resize(320, 240)
        self.show_all()

    def on_open(self, action):
        dlg = Gtk.FileChooserDialog(
                "ファイルを開く", self,
                Gtk.FileChooserAction.OPEN,
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, 
                Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        dlg.run()
        dlg.destroy()

    def on_quit(self, action):
        Gtk.main_quit()

GearsMenuWin()
Gtk.main()

img2/menubutton.png

GtkMenuBar, GtkToolbar

GtkUIManager が非推奨になったのでコードで作るしかなくなりました。

GtkMenu を作るまでは上記と同じです。
GtkMenuItem にハンドラとアクセラレータを登録。
append で GtkMenu に詰め込む。

それを更に GtkMenuItem に入れて[ファイル(F)]等のアイテムを作る。
それを GtkMenuBar に登録、という流れになります。
ちなみに F10 キーでのドロップは GTK+ がやってくれる。

ツールバーはツールチップも付けたほうがいいですね。
こっちは単純なのでコードを見ればなんとなく解ると思う。
ハンドラはメニューと同じものを参照すればいい。
#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

class Win(Gtk.Window):
    """
        MenuBar, Toolbar を普通に作る
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        # MenuIten
        item_open = Gtk.MenuItem.new_with_mnemonic("_Open")
        item_open.connect("activate", self.on_open)
        item_quit = Gtk.MenuItem.new_with_mnemonic("_Quit")
        item_quit.connect("activate", self.on_quit)
        # Add Accelerator
        accelgroup = Gtk.AccelGroup.new()
        self.add_accel_group(accelgroup)
        item_open.add_accelerator("activate", accelgroup, Gdk.KEY_o, 
                Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
        item_quit.add_accelerator("activate", accelgroup, Gdk.KEY_q, 
                Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
        # Separator
        item_separator = Gtk.SeparatorMenuItem.new()
        # Menu
        file_sub_menu = Gtk.Menu.new()
        file_sub_menu.append(item_open)
        file_sub_menu.append(item_separator)
        file_sub_menu.append(item_quit)
        # Top MenuItem
        file_root_menu = Gtk.MenuItem.new_with_mnemonic("_File")
        file_root_menu.set_submenu(file_sub_menu)
        # MenuBar
        menubar = Gtk.MenuBar.new()
        menubar.append(file_root_menu)
        #
        # Toolbar
        tool_open = Gtk.ToolButton.new_from_stock(Gtk.STOCK_OPEN)
        tool_open.set_tooltip_text("開く")
        tool_open.connect("clicked", self.on_open)
        tool_quit = Gtk.ToolButton.new_from_stock(Gtk.STOCK_QUIT)
        tool_quit.set_tooltip_text("終了")
        tool_quit.connect("clicked", self.on_quit)
        tool_separator = Gtk.SeparatorToolItem.new()
        toolbar = Gtk.Toolbar.new()
        toolbar.insert(tool_open, 0)
        toolbar.insert(tool_separator, 1)
        toolbar.insert(tool_quit, 2)
        #
        # パッキング
        drawingarea = Gtk.DrawingArea()
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(menubar, False, True, 0)
        vbox.pack_start(toolbar, False, True, 0)
        vbox.pack_start(drawingarea, True, True, 0)
        self.add(vbox)
        # いつもの処理
        self.set_title("Only MenuBar")
        self.connect("delete-event", self.on_quit)
        self.resize(320, 240)
        self.show_all()

    def on_open(self, widget):
        pass

    def on_quit(self, widget):
        Gtk.main_quit()

if __name__ == "__main__":
    Win()
    Gtk.main()

右クリックメニューは割愛します。

MenuBar, Toolbar なので注意、統一される前に無くなるかな。
Copyright(C) sasakima-nao All rights reserved 2002 --- 2017.