wxWidgets 中的菜单和工具栏
最后修改于 2023 年 10 月 18 日
菜单栏是 GUI 应用程序中最显眼的部分之一。 它是一组位于各种菜单中的命令。 虽然在控制台应用程序中,你必须记住所有那些晦涩的命令,但在这里,我们的大部分命令都分组到逻辑部分。 有一些公认的标准可以进一步减少学习新应用程序所花费的时间。 要在 wxWidgets 中实现菜单栏,我们需要三个类:wxMenuBar
, wxMenu
和 wxMenuItem
。
简单的菜单示例
在 wxWidgets 中创建菜单栏非常简单。
#include <wx/wx.h> #include <wx/menu.h> class SimpleMenu : public wxFrame { public: SimpleMenu(const wxString& title); void OnQuit(wxCommandEvent& event); wxMenuBar *menubar; wxMenu *file; };
#include "menu.h" SimpleMenu::SimpleMenu(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(280, 180)) { menubar = new wxMenuBar; file = new wxMenu; file->Append(wxID_EXIT, wxT("&Quit")); menubar->Append(file, wxT("&File")); SetMenuBar(menubar); Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SimpleMenu::OnQuit)); Centre(); } void SimpleMenu::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
#include "main.h" #include "menu.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { SimpleMenu *menu = new SimpleMenu(wxT("Simple Menu")); menu->Show(true); return true; }
menubar = new wxMenuBar;
首先,我们创建一个菜单栏对象。
file = new wxMenu;
接下来,我们创建一个菜单对象。
file->Append(wxID_EXIT, wxT("&Quit"));
我们将一个菜单项附加到菜单对象中。 第一个参数是菜单项的 ID。 第二个参数是菜单项的名称。 在这里,我们没有显式地创建 wxMenuItem
。 它是由 Append
方法在幕后创建的。 稍后,我们将手动创建 wxMenuItem
。
menubar->Append(file, wxT("&File")); SetMenuBar(menubar);
之后,我们将一个菜单附加到菜单栏。 & 字符创建了一个快捷键。 在 & 字符后面的字符会带有下划线。 这样就可以通过 Alt+F 快捷方式访问菜单。 最后,我们调用 SetMenuBar
方法。 此方法属于 wxFrame
窗口部件。 它设置了菜单栏。

子菜单
每个菜单也可以有一个子菜单。 通过这种方式,我们可以将相似的命令分组到组中。 例如,我们可以将隐藏或显示各种工具栏的命令(如个人栏、地址栏、状态栏或导航栏)放入一个名为“工具栏”的子菜单中。 在菜单中,我们可以用分隔符分隔命令。 这是一个简单的线条。 通常的做法是用一个分隔符分隔类似新建、打开、保存的命令和类似打印、打印预览的命令。 在我们的示例中,我们看到了如何创建子菜单和菜单分隔符。
#include <wx/wx.h> #include <wx/menu.h> class SubMenu : public wxFrame { public: SubMenu(const wxString& title); void OnQuit(wxCommandEvent & event); wxMenuBar *menubar; wxMenu *file; wxMenu *imp; wxMenuItem *quit; };
#include "menu.h" SubMenu::SubMenu(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(280, 180)) { menubar = new wxMenuBar; file = new wxMenu; file->Append(wxID_ANY, wxT("&New")); file->Append(wxID_ANY, wxT("&Open")); file->Append(wxID_ANY, wxT("&Save")); file->AppendSeparator(); imp = new wxMenu; imp->Append(wxID_ANY, wxT("Import newsfeed list...")); imp->Append(wxID_ANY, wxT("Import bookmarks...")); imp->Append(wxID_ANY, wxT("Import mail...")); file->AppendSubMenu(imp, wxT("I&mport")); quit = new wxMenuItem(file, wxID_EXIT, wxT("&Quit\tCtrl+W")); file->Append(quit); menubar->Append(file, wxT("&File")); SetMenuBar(menubar); Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SubMenu::OnQuit)); Centre(); } void SubMenu::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
#include "main.h" #include "menu.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { SubMenu *smenu = new SubMenu(wxT("Submenu")); smenu->Show(true); return true; }
我们在文件菜单中创建了一个子菜单。 它是一个导入子菜单,可以在 Opera 浏览器中看到。
file->AppendSeparator();
通过调用 AppendSeparator
方法可以创建菜单分隔线。
imp = new wxMenu; imp->Append(wxID_ANY, wxT("Import newsfeed list...")); imp->Append(wxID_ANY, wxT("Import bookmarks...")); imp->Append(wxID_ANY, wxT("Import mail...")); file->AppendSubMenu(imp, wxT("I&mport"));
子菜单的创建类似于普通菜单。 它通过 AppendSubMenu
方法附加。

工具栏
菜单将我们在应用程序中可以使用的所有命令分组。工具栏提供对最常用命令的快速访问。
virtual wxToolBar* wxFrame::CreateToolBar(long style = wxTB_DEFAULT_STYLE, wxWindowID id = wxID_ANY, const wxString & name = wxToolBarNameStr)
要创建工具栏,我们调用框架窗口部件的 CreateToolBar
方法。
一个简单的工具栏
我们的第一个示例将创建一个简单的工具栏。
#include <wx/wx.h> class Toolbar : public wxFrame { public: Toolbar(const wxString& title); void OnQuit(wxCommandEvent& event); };
#include "toolbar.h" Toolbar::Toolbar(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 250)) { wxImage::AddHandler(new wxPNGHandler); wxBitmap exit(wxT("exit.png"), wxBITMAP_TYPE_PNG); wxToolBar *toolbar = CreateToolBar(); toolbar->AddTool(wxID_EXIT, wxT("Exit application"), exit); toolbar->Realize(); Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(Toolbar::OnQuit)); } void Toolbar::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
#include "main.h" #include "toolbar.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Toolbar *toolbar = new Toolbar(wxT("Toolbar")); toolbar->Show(true); return true; }
在我们的示例中,我们创建了一个工具栏和一个工具按钮。 单击工具栏按钮将终止应用程序。
wxToolBar *toolbar = CreateToolBar();
我们创建一个工具栏。
toolbar->AddTool(wxID_EXIT, wxT("Exit application"), exit);
我们向工具栏添加一个工具。
toolbar->Realize();
添加工具后,我们调用 Realize
方法。

工具栏
如果我们想拥有多个工具栏,我们必须以不同的方式创建它们,例如,而不是调用 CreateToolbar
方法。
#include <wx/wx.h> class Toolbar : public wxFrame { public: Toolbar(const wxString& title); void OnQuit(wxCommandEvent& event); wxToolBar *toolbar1; wxToolBar *toolbar2; };
#include "toolbars.h" Toolbar::Toolbar(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 250)) { wxImage::AddHandler(new wxPNGHandler); wxBitmap exit(wxT("exit.png"), wxBITMAP_TYPE_PNG); wxBitmap newb(wxT("new.png"), wxBITMAP_TYPE_PNG); wxBitmap open(wxT("open.png"), wxBITMAP_TYPE_PNG); wxBitmap save(wxT("save.png"), wxBITMAP_TYPE_PNG); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); toolbar1 = new wxToolBar(this, wxID_ANY); toolbar1->AddTool(wxID_ANY, wxT("New"), newb); toolbar1->AddTool(wxID_ANY, wxT("Open"), open); toolbar1->AddTool(wxID_ANY, wxT(""), save); toolbar1->Realize(); toolbar2 = new wxToolBar(this, wxID_ANY); toolbar2->AddTool(wxID_EXIT, wxT("Exit application"), exit); toolbar2->Realize(); vbox->Add(toolbar1, 0, wxEXPAND); vbox->Add(toolbar2, 0, wxEXPAND); SetSizer(vbox); Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(Toolbar::OnQuit)); } void Toolbar::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); };
#include "main.h" #include "toolbars.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Toolbar *toolbar = new Toolbar(wxT("Toolbar")); toolbar->Show(true); return true; }
在我们的示例中,我们创建了两个水平工具栏。 我们将它们放置在一个垂直框布局管理器中。
toolbar1 = new wxToolBar(this, wxID_ANY); ... toolbar2 = new wxToolBar(this, wxID_ANY);
在这里我们创建了两个工具栏。
vbox->Add(toolbar1, 0, wxEXPAND); vbox->Add(toolbar2, 0, wxEXPAND);
在这里我们将它们添加到垂直框布局管理器中。

在 wxWidgets 教程的这一部分,我们介绍了菜单和工具栏。