この章では、アプリケーションのメニュー、ステータスバー、ツールバーを説明します。
#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; menubar->Append(file, "File"); file->Append(wxID_EXIT, "Quit"); 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; }
#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; }
#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; }
#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よりも新しい手法です。
#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 を使っています。
#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; }
次の toolbar.cpp で使われている std::to_string() という関数は、g++ のバージョン 7 以上が必要です。Mint 18 と Ubuntu 16.04 のデフォルトの g++ は、バージョン 4 か 5 です。ターミナルで次のコマンドを実行して バージョン 9 をインストールしてください。この作業は、Mint 18 と Ubuntu 16.04 以外では必要ありません。
std::to_string()
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install -y g++-9
コンパイルする時は次のようにします。 g++-9 toolbar.cpp `wx-config --cppflags --libs` -o ToolBar デフォルトの g++ を使う場合は、今までとおりに次のようにします。 g++ ~~~~.cpp `wx-config -cppflags --libs` -o ~~~~
g++-9 toolbar.cpp `wx-config --cppflags --libs` -o ToolBar
g++ ~~~~.cpp `wx-config -cppflags --libs` -o ~~~~
#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 で提供されているビットマップイメージを使っています。