メニューバー

概要

メニューバーを表示する。

基本的にはポップアップメニューと同様にアクションをアクショングループに登録してUIマネージャでレイアウトしてから メニューバーをパックすれば良い。なおメニューバーのアクションとポップアップメニューのアクションはわざわざ別々に 作らなくても共通に使うことが出来るのに注意すること。以下のサンプルではメニューバーの表示だけではなく クライアント領域をクリックしたときにポップアップメニューも表示するようにしてある。

ソース

menubar.cpp
#include <gtkmm.h>
#include <iostream>

class MainWin : public Gtk::Window
{
    Gtk::VBox m_box;

    Glib::RefPtr< Gtk::ActionGroup > m_actiongroup;
    Glib::RefPtr< Gtk::UIManager > m_uimanager;

public:
    MainWin();

private:
    void on_menu_test1();
    void on_menu_test2();
    
protected:
    virtual bool on_button_press_event( GdkEventButton* event );
};


MainWin::MainWin()
{
    // OFFになってるイベントを追加
    add_events( Gdk::BUTTON_PRESS_MASK );

    // アクショングループの作成とアクション登録
    m_actiongroup = Gtk::ActionGroup::create();

    // メニューのラベル
    m_actiongroup->add( Gtk::Action::create( "MenuTitle1", "メニュー1" ) );
    m_actiongroup->add( Gtk::Action::create( "SubMenu", "サブメニュー" ) );
    m_actiongroup->add( Gtk::Action::create( "MenuTitle2", "メニュー2" ) );

    // ポップアップメニュのラベル
    m_actiongroup->add( Gtk::Action::create( "PopupMenuTitle", "ポップアップメニュー" ) );

    // 共通アクション
    m_actiongroup->add( Gtk::Action::create( "TestMenu1", "テスト1" ), sigc::mem_fun( *this, &MainWin::on_menu_test1 ) );    
    m_actiongroup->add( Gtk::Action::create( "TestMenu2", "テスト2" ), sigc::mem_fun( *this, &MainWin::on_menu_test2 ) );    

    // UIマネージャの作成とアクショングループ挿入
    m_uimanager = Gtk::UIManager::create();
    m_uimanager->insert_action_group( m_actiongroup );

    // メニューのレイアウト
    try
    {
        Glib::ustring ui_info = 
            "<ui>"

            // メニュー
            "<menubar name='MenuBar'>"
            "   <menu action='MenuTitle1'>"
            "      <menu action='SubMenu'>"
            "        <menuitem action='TestMenu1'/>"
            "        <menuitem action='TestMenu2'/>"
            "     </menu>"
            "     <separator/>"
            "     <menuitem action='TestMenu2'/>"
            "  </menu>"
            "   <menu action='MenuTitle2'>"
            "      <menuitem action='TestMenu1'/>"
            "      <menuitem action='TestMenu2'/>"
            "  </menu>"
            "</menubar>"

            // ポップアップメニュー
            "<popup name='PopupMenu' >"
            "  <menuitem action='PopupMenuTitle'/>"
            "  <menuitem action='TestMenu1'/>"
            "  <menuitem action='TestMenu2'/>"
            "</popup>"

            "</ui>";

        m_uimanager->add_ui_from_string(ui_info);
    }
    catch(const Glib::Error& err )
    {
        std::cout << err.what() << std::endl;
    }

    // メニューのパック
    resize( 300, 300 );
    add( m_box );
    Gtk::Widget* menubar = m_uimanager->get_widget( "/MenuBar" );
    m_box.pack_start( *menubar, Gtk::PACK_SHRINK );
    show_all_children();
}



// マウスクリック
bool MainWin::on_button_press_event( GdkEventButton* event )
{
    Gtk::Menu* popupmenu = dynamic_cast< Gtk::Menu* >( m_uimanager->get_widget( "/PopupMenu" ) );
    popupmenu->popup( event->button, event->time );

    return true;
}


// シグナルハンドラ
void MainWin::on_menu_test1()
{
    std::cout << "test1\n";
}


// シグナルハンドラ
void MainWin::on_menu_test2()
{
    std::cout << "test2\n";
}



int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}

コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ menubar.cpp -o menubar `pkg-config gtkmm-2.4 --cflags --libs`

結果