wxWidgets   メニュー

ホーム   C/C++チュートリアル


メニュー


この章では、アプリケーションのメニュー、ステータスバー、ツールバーを説明します。

menu.cpp


#include <wx/wx.h>
#include <wx/menu.h>

class Menu : public wxFrame
{
public:
    Menu();
    void OnQuit(wxCommandEvent &event);
    wxMenuBar *menubar;
    wxMenu    *file;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

Menu::Menu() : wxFrame(NULL, -1, "Menu")
{
    menubar = new wxMenuBar;
    file    = new wxMenu;
    file->Append(wxID_EXIT, "Quit");
    menubar->Append(file, "File");
    SetMenuBar(menubar);
    
    Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Menu::OnQuit));
}

void Menu::OnQuit(wxCommandEvent &event)
{
    Close(true);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Menu *menu = new Menu();
    menu->Show();
    return true;
}
    


windows

File メニューの Quit を選択すると、アプリケーションが終了します。


macOS

macOS では、File メニュー ではなく、アプリケーションメニューの Quit アプリケーション名 を選択すると、アプリケーションが終了します。キーボードで、⌘Q(command + Q)を押しても、アプリケーションを終了できます。


サブメニュー

submenu.cpp


#include <wx/wx.h>
#include <wx/menu.h>

class SubMenu : public wxFrame
{
public:
    SubMenu();
    void OnQuit(wxCommandEvent & event);
    wxMenuBar  *menubar;
    wxMenu     *file;
    wxMenu     *imp;
    wxMenuItem *quit;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

SubMenu::SubMenu() : wxFrame(NULL, -1, "SubMenu")
{
    menubar = new wxMenuBar;
    file    = new wxMenu;
    
    file->Append(wxID_NEW,  wxT("新規"));
    file->Append(wxID_OPEN, wxT("開く"));
    file->Append(wxID_SAVE, wxT("保存"));
    file->AppendSeparator();
    
    imp    = new wxMenu;
    imp->Append(-1, wxT("ブックマークをインポート"));
    imp->Append(-1, wxT("メールをインポート"));
    file->AppendSubMenu(imp, wxT("インポート"));
    
    quit   = new wxMenuItem(file, wxID_EXIT, wxT("終了\tCtrl+Q"));
    file->Append(quit);
    
    menubar->Append(file, wxT("ファイル"));
    SetMenuBar(menubar);
    
    Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SubMenu::OnQuit));
}

void SubMenu::OnQuit(wxCommandEvent & event)
{
    Close(true);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    SubMenu *submenu = new SubMenu();
    submenu->Show();
    return true;
}
    


Windows

Control Q もしくは、Windowsキー Q でもアプリケーションを終了できます。


定義済みメニュー

predefinedmenu.cpp


#include <wx/wx.h>
#include <wx/menu.h>

class PredefinedMenu : public wxFrame
{
public:
    PredefinedMenu();
    wxMenuBar *menubar;
    wxMenu    *filemenu;
    wxMenu    *editmenu;
    wxMenu    *helpmenu;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

PredefinedMenu::PredefinedMenu() : wxFrame(NULL, -1, "PredefinedMenu")
{
    menubar  = new wxMenuBar();
    filemenu = new wxMenu();
    editmenu = new wxMenu();
    helpmenu = new wxMenu();
    
    filemenu->Append(wxID_ABOUT);
    filemenu->AppendSeparator();
    filemenu->Append(wxID_NEW);
    filemenu->Append(wxID_OPEN);
    filemenu->Append(wxID_SAVE);
    filemenu->AppendSeparator();
    filemenu->Append(wxID_SAVEAS);
    filemenu->Append(wxID_CLOSE);
    filemenu->AppendSeparator();
    filemenu->Append(wxID_EXIT);
    
    editmenu->Append(wxID_UNDO);
    editmenu->Append(wxID_REDO);
    editmenu->AppendSeparator();
    editmenu->Append(wxID_COPY);
    editmenu->Append(wxID_CUT);
    editmenu->Append(wxID_PASTE);
    editmenu->Append(wxID_DELETE);
    
    helpmenu->Append(wxID_HELP);
    
    menubar->Append(filemenu, "File");
    menubar->Append(editmenu, "Edit");
    menubar->Append(helpmenu, "Help");
    SetMenuBar(menubar);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    PredefinedMenu *predefinedmenu = new PredefinedMenu();
    predefinedmenu->Show();
    return true;
}
	


Mint

Mint(Ubuntu)では定義済みメニューを使うとメニューに画像がつきます。WindowsとmacOSではつきません。
wxID_EXITを指定すると、コードを実装しなくても、WindowsではWindowsキーQというショートカットキーで、 macOSでは⌘Qというショートカットキーで、アプリケーションを終了できます。
Mint(Ubunt)ではこの機能はなくコードを実装しなければ終了できません。


チェックメニュー

checkmenu.cpp


#include <wx/wx.h>
#include <wx/menu.h>

class CheckMenu : public wxFrame
{
public:
    CheckMenu();
    void OnCheck(wxCommandEvent & event);
    wxMenuBar    *menubar;
    wxMenu       *filemenu;
    wxBoxSizer   *hbox;
    wxBoxSizer   *vbox;
    wxStaticText *statictext;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

CheckMenu::CheckMenu() : wxFrame(NULL, -1, "CheckMenu")
{
    menubar    = new wxMenuBar();
    filemenu   = new wxMenu();
    filemenu->AppendCheckItem(1001, wxT("チェックメニュー"));
    statictext = new wxStaticText(this, -1, wxT("未選択"));
    hbox       = new wxBoxSizer(wxHORIZONTAL);
    hbox->Add(statictext, 1, wxALIGN_CENTER);
    vbox       = new wxBoxSizer(wxVERTICAL);
    vbox->Add(hbox, 1, wxLEFT, 10);
    
    menubar->Append(filemenu, "File");
    SetMenuBar(menubar);
    SetSizer(vbox);
    
    Bind(wxEVT_COMMAND_MENU_SELECTED, &CheckMenu::OnCheck, this, 1001);
    //Connect(1001, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CheckMenu::OnCheck));
}

void CheckMenu::OnCheck(wxCommandEvent & event)
{
    if (menubar->IsChecked(1001)) {
        statictext->SetLabel(wxT("チェックされました"));
    } else {
        statictext->SetLabel(wxT("未選択"));
    }
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    CheckMenu *checkmenu = new CheckMenu();
    checkmenu->Show();
    return true;
}
	

今回は、イベントとイベントハンドラー(そのイベントを処理する関数)を結びつけるために、Connect( ) 関数の代わりに Bind( ) 関数を使ってみました。Bindのほうが、Connectよりも新しい手法です。

Windows


コンテキストメニュー

context.cpp


#include <wx/wx.h>

class Context : public wxFrame
{
public:
    Context();
    void OnRightDown(wxCommandEvent & event);
    void OnMinimize(wxCommandEvent & event);
    void OnQuit(wxCommandEvent & event);
    wxMenu * menu;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

Context::Context() : wxFrame(NULL, 101, "Context")
{
    menu = new wxMenu();
    menu->Append(1001, "Minimize");
    menu->Append(wxID_EXIT);
    
    Connect(101, wxEVT_RIGHT_DOWN, wxCommandEventHandler(Context::OnRightDown));
    
    Bind(wxEVT_MENU, &Context::OnMinimize, this, 1001);
    
    Bind(wxEVT_MENU, &Context::OnQuit, this, wxID_EXIT);
}

void Context::OnRightDown(wxCommandEvent & event)
{
    PopupMenu(menu);
}

void Context::OnMinimize(wxCommandEvent & event)
{
    Iconize();
}

void Context::OnQuit(wxCommandEvent & event)
{
    Close();
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Context *context = new Context();
    context->Show();
    return true;
}
	

右クリックした場合の Bind の方法が分からず、このイベントだけ Connect を使っています。


ウィンドウ内を右クリックすると、その場所にメニューが現れます。Minimize を選択すると、ウィンドウが最小化します。


ステータスバー

statusbar.cpp


#include <wx/wx.h>
#include <wx/menu.h>

class StatusBar : public wxFrame
{
public:
    StatusBar();
    void ShowStatusBar(wxCommandEvent & event);
    void ShowWxWidgets(wxCommandEvent & event);
    wxMenuBar *menubar;
    wxMenu    *view;
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

StatusBar::StatusBar() : wxFrame(NULL, -1, "StatusBar")
{
    menubar = new wxMenuBar;
    view    = new wxMenu;
    view->AppendCheckItem(1001, "Show StatusBar");
    view->AppendCheckItem(1002, "Show wxWidgets");
    view->Check(1001, true);
    menubar->Append(view, "View");
    SetMenuBar(menubar);
    CreateStatusBar();
    
    Bind(wxEVT_COMMAND_MENU_SELECTED, &StatusBar::ShowStatusBar, this, 1001);
    
    Bind(wxEVT_COMMAND_MENU_SELECTED, &StatusBar::ShowWxWidgets, this, 1002);
}

void StatusBar::ShowStatusBar(wxCommandEvent & event)
{
    if (menubar->IsChecked(1001)) {
        GetStatusBar()->Show();
    } else {
        GetStatusBar()->Hide(); 
    }
}

void StatusBar::ShowWxWidgets(wxCommandEvent & event)
{
    if (menubar->IsChecked(1002)) {
        SetStatusText("wxWidgets");
    } else {
        SetStatusText("");
    }
}


IMPLEMENT_APP(App)

bool App::OnInit()
{
    StatusBar *statusbar = new StatusBar();
    statusbar->Show();
    return true;
}
	


Windows

Mint


ツールバー

次の toolbar.cpp で使われている std::to_string() という関数は、g++ のバージョン 7 以上が必要です。Mint 18 と Ubuntu 16.04 のデフォルトの g++ は、バージョン 4 か 5 です。ターミナルで次のコマンドを実行して バージョン 9 をインストールしてください。この作業は、Mint 18 と Ubuntu 16.04 以外では必要ありません。

  1. sudo add-apt-repository ppa:ubuntu-toolchain-r/test
  2. sudo apt update
  3. sudo apt install -y g++-9

コンパイルする時は次のようにします。
g++-9 toolbar.cpp `wx-config --cppflags --libs` -o ToolBar
デフォルトの g++ を使う場合は、今までとおりに次のようにします。
g++ ~~~~.cpp `wx-config -cppflags --libs` -o ~~~~

toolbar.cpp


#include <wx/wx.h>
#include <wx/artprov.h>

class ToolBar : public wxFrame
{
public:
    ToolBar();
    wxStaticText *text;
    wxToolBar    *toolbar;
    void OnUndo(wxCommandEvent & event);
    void OnRedo(wxCommandEvent & event);
    void OnQuit(wxCommandEvent & event);
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

ToolBar::ToolBar() : wxFrame(NULL, -1, "ToolBar")
{
    wxImage::AddHandler(new wxPNGHandler);
    wxBitmap undo = wxArtProvider::GetBitmap(wxART_UNDO);
    wxBitmap redo = wxArtProvider::GetBitmap(wxART_REDO);
    wxBitmap exit = wxArtProvider::GetBitmap(wxART_QUIT);
    
    toolbar = CreateToolBar();
    toolbar->AddTool(wxID_UNDO, "Undo", undo);
    toolbar->AddTool(wxID_REDO, "Redo", redo);
    toolbar->AddSeparator();
    toolbar->AddTool(wxID_EXIT, "Quit", exit);
    toolbar->Realize();
    toolbar->EnableTool(wxID_REDO, false);
    
    text = new wxStaticText(this,101, "5");
    wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
    hbox->Add(text, 1, wxALIGN_CENTER);
    vbox->Add(hbox, 1, wxALIGN_CENTER);
    SetSizer(vbox);
    
    Bind(wxEVT_COMMAND_TOOL_CLICKED, &ToolBar::OnUndo, this, wxID_UNDO);
    
    Bind(wxEVT_COMMAND_TOOL_CLICKED, &ToolBar::OnRedo, this, wxID_REDO);
    
    Bind(wxEVT_COMMAND_TOOL_CLICKED, &ToolBar::OnQuit, this, wxID_EXIT);
}

void ToolBar::OnUndo(wxCommandEvent & event)
{
    int num = atoi(text->GetLabel());
    num--;
    switch (num)
    {
        case 0:
            toolbar->EnableTool(wxID_UNDO, false);
            break;
        case 4:
            toolbar->EnableTool(wxID_REDO, true);
            break;
    }
    text->SetLabel(std::to_string(num));
}

void ToolBar::OnRedo(wxCommandEvent & event)
{
    int num = atoi(text->GetLabel());
    num++;
    switch (num)
    {
        case 1:
            toolbar->EnableTool(wxID_UNDO, true);
            break;
        case 5:
            toolbar->EnableTool(wxID_REDO, false);
            break;
    }
    text->SetLabel(std::to_string(num));
}

void ToolBar::OnQuit(wxCommandEvent & event)
{
    Close();
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    ToolBar *toolbar = new ToolBar();
    toolbar->Show();
    return true;
}
	

今回は、wxArtProvider で提供されているビットマップイメージを使っています。

Windows

macOS

Mint



193 visits
Posted: Nov. 27, 2019
Update: Nov. 27, 2019

ホーム   C/C++チュートリアル   目次