ポップアップメニュー

概要

ウィンドウのクライアント領域をクリックしたときにポップアップメニューを表示する。

ポップアップメニューの各メニュー項目はシグナルとシグナルハンドラを介して実行される。すなわちユーザが ポップアップメニューからあるメニュー項目を選択するとシグナルが発せられて対応したシグナルハンドラが呼び出される。

具体的にはアクショングループ( Gtk::ActionGroup ) に各メニュー項目のアクション( Gtk::Action )を登録し、UIマネージャ( Gtk::UIManager )にアクショングループを挿入し メニューのレイアウトをおこない、Gtk::Menu::popup()によってポップアップメニューを表示する。

ソース

pmenu.cpp

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

class MainWin : public Gtk::Window
{
    Glib::RefPtr< Gtk::ActionGroup > m_actiongroup;
    Glib::RefPtr< Gtk::UIManager > m_uimanager;

public:
    MainWin();

private:
    void on_popupmenu_test();
    
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( "MenuTitle", "メニュー" ) );
    m_actiongroup->add( Gtk::Action::create( "TestMenu", "テスト"), sigc::mem_fun( *this, &MainWin::on_popupmenu_test ) );    

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

    // ポップアップメニューのレイアウト
    Glib::ustring ui_info = 
        "<ui>"
        "<popup name='PopupMenu' >"
        "<menuitem action='MenuTitle'/>"
        "<menuitem action='TestMenu'/>"
        "</popup>"
        "</ui>";
    m_uimanager->add_ui_from_string(ui_info);
}


// マウスクリック
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_popupmenu_test()
{
    std::cout << "ok\n";
}


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

    return 0;
}

コンパイル

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

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

結果