原文: http://zetcode.com/gui/wxwidgets/menustoolbars/

菜单栏是 GUI 应用中最可见的部分之一。 它是位于各个菜单中的一组命令。 在控制台应用中,您必须记住所有这些神秘命令,在这里,我们将大多数命令分组为逻辑部分。 有公认的标准可以进一步减少学习新应用的时间。 要在 wxWidgets 中实现菜单栏,我们需要三个类:wxMenuBarwxMenuwxMenuItem

简单菜单示例

在 wxWidgets 中创建菜单栏非常简单。

menu.h

  1. #include <wx/wx.h>
  2. #include <wx/menu.h>
  3. class SimpleMenu : public wxFrame
  4. {
  5. public:
  6. SimpleMenu(const wxString& title);
  7. void OnQuit(wxCommandEvent& event);
  8. wxMenuBar *menubar;
  9. wxMenu *file;
  10. };

menu.cpp

  1. #include "menu.h"
  2. SimpleMenu::SimpleMenu(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(280, 180))
  4. {
  5. menubar = new wxMenuBar;
  6. file = new wxMenu;
  7. file->Append(wxID_EXIT, wxT("&Quit"));
  8. menubar->Append(file, wxT("&File"));
  9. SetMenuBar(menubar);
  10. Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
  11. wxCommandEventHandler(SimpleMenu::OnQuit));
  12. Centre();
  13. }
  14. void SimpleMenu::OnQuit(wxCommandEvent& WXUNUSED(event))
  15. {
  16. Close(true);
  17. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "menu.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. SimpleMenu *menu = new SimpleMenu(wxT("Simple Menu"));
  7. menu->Show(true);
  8. return true;
  9. }
  1. menubar = new wxMenuBar;

首先,我们创建一个菜单栏对象。

  1. file = new wxMenu;

接下来,我们创建一个菜单对象。

  1. file->Append(wxID_EXIT, wxT("&Quit"));

我们将菜单项添加到菜单对象中。 第一个参数是菜单项的 ID。 第二个参数是菜单项的名称。 在这里,我们没有明确创建一个wxMenuItem。 它是通过Append()方法在后台创建的。 稍后,我们将手动创建wxMenuItem

  1. menubar->Append(file, wxT("&File"));
  2. SetMenuBar(menubar);

之后,我们将菜单添加到菜单栏中。 &字符创建一个加速键。 带下划线的&后面的字符。 这样,可以通过 Alt + F 快捷方式访问菜单。 最后,我们调用SetMenuBar()方法。 该方法属于wxFrame小部件。 它设置菜单栏。

wxWidgets 中的菜单和工具栏 - 图1

图:简单菜单 example

子菜单

每个菜单也可以有一个子菜单。 这样,我们可以将类似的命令分组。 例如,我们可以将隐藏或显示各种工具栏(例如个人栏,地址栏,状态栏或导航栏)的命令放置在称为工具栏的子菜单中。 在菜单中,我们可以使用分隔符来分隔命令。 这是一条简单的线。 通常的做法是使用单个分隔符将命令(例如新建,打开,保存)与命令(例如打印,打印预览)分开。 在我们的示例中,我们将看到如何创建子菜单和菜单分隔符。

menu.h

  1. #include <wx/wx.h>
  2. #include <wx/menu.h>
  3. class SubMenu : public wxFrame
  4. {
  5. public:
  6. SubMenu(const wxString& title);
  7. void OnQuit(wxCommandEvent & event);
  8. wxMenuBar *menubar;
  9. wxMenu *file;
  10. wxMenu *imp;
  11. wxMenuItem *quit;
  12. };

menu.cpp

  1. #include "menu.h"
  2. SubMenu::SubMenu(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(280, 180))
  4. {
  5. menubar = new wxMenuBar;
  6. file = new wxMenu;
  7. file->Append(wxID_ANY, wxT("&New"));
  8. file->Append(wxID_ANY, wxT("&Open"));
  9. file->Append(wxID_ANY, wxT("&Save"));
  10. file->AppendSeparator();
  11. imp = new wxMenu;
  12. imp->Append(wxID_ANY, wxT("Import newsfeed list..."));
  13. imp->Append(wxID_ANY, wxT("Import bookmarks..."));
  14. imp->Append(wxID_ANY, wxT("Import mail..."));
  15. file->AppendSubMenu(imp, wxT("I&mport"));
  16. quit = new wxMenuItem(file, wxID_EXIT, wxT("&Quit\tCtrl+W"));
  17. file->Append(quit);
  18. menubar->Append(file, wxT("&File"));
  19. SetMenuBar(menubar);
  20. Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
  21. wxCommandEventHandler(SubMenu::OnQuit));
  22. Centre();
  23. }
  24. void SubMenu::OnQuit(wxCommandEvent& WXUNUSED(event))
  25. {
  26. Close(true);
  27. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "menu.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. SubMenu *smenu = new SubMenu(wxT("Submenu"));
  7. smenu->Show(true);
  8. return true;
  9. }

我们在文件菜单中创建了一个子菜单。 这是一个导入子菜单,可以在 Opera Web 浏览器中看到。

  1. file->AppendSeparator();

创建菜单分隔线,并调用AppendSeparator()方法。

  1. imp = new wxMenu;
  2. imp->Append(wxID_ANY, wxT("Import newsfeed list..."));
  3. imp->Append(wxID_ANY, wxT("Import bookmarks..."));
  4. imp->Append(wxID_ANY, wxT("Import mail..."));
  5. file->AppendSubMenu(imp, wxT("I&mport"));

子菜单的创建类似于普通菜单。 它附有AppendSubMenu()方法。

wxWidgets 中的菜单和工具栏 - 图2

图:子菜单

工具栏

菜单将我们可以在应用中使用的所有命令分组。 使用工具栏可以快速访问最常用的命令。

  1. virtual wxToolBar* wxFrame::CreateToolBar(long style = wxTB_DEFAULT_STYLE,
  2. wxWindowID id = wxID_ANY, const wxString & name = wxToolBarNameStr)

要创建工具栏,我们调用框架窗口小部件的CreateToolBar()方法。

一个简单的工具栏

我们的第一个示例将创建一个简单的工具栏。

toolbar.h

  1. #include <wx/wx.h>
  2. class Toolbar : public wxFrame
  3. {
  4. public:
  5. Toolbar(const wxString& title);
  6. void OnQuit(wxCommandEvent& event);
  7. };

toolbar.cpp

  1. #include "toolbar.h"
  2. Toolbar::Toolbar(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title,
  4. wxDefaultPosition, wxSize(300, 250)) {
  5. wxImage::AddHandler(new wxPNGHandler);
  6. wxBitmap exit(wxT("exit.png"), wxBITMAP_TYPE_PNG);
  7. wxToolBar *toolbar = CreateToolBar();
  8. toolbar->AddTool(wxID_EXIT, wxT("Exit application"), exit);
  9. toolbar->Realize();
  10. Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED,
  11. wxCommandEventHandler(Toolbar::OnQuit));
  12. }
  13. void Toolbar::OnQuit(wxCommandEvent& WXUNUSED(event)) {
  14. Close(true);
  15. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp {
  3. public:
  4. virtual bool OnInit();
  5. };

main.cpp

  1. #include "main.h"
  2. #include "toolbar.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit() {
  5. Toolbar *toolbar = new Toolbar(wxT("Toolbar"));
  6. toolbar->Show(true);
  7. return true;
  8. }

在我们的示例中,我们创建了一个工具栏和一个工具按钮。 单击工具栏按钮将终止应用。

  1. wxToolBar *toolbar = CreateToolBar();

我们创建一个工具栏。

  1. toolbar->AddTool(wxID_EXIT, wxT("Exit application"), exit);

我们将工具添加到工具栏。

  1. toolbar->Realize();

添加工具后,我们将调用Realize()方法。

wxWidgets 中的菜单和工具栏 - 图3

图:工具栏

工具栏

如果我们要拥有多个工具栏,则必须以其他方式创建它们,例如除了调用CreateToolbar()方法。

toolbars.h

  1. #include <wx/wx.h>
  2. class Toolbar : public wxFrame {
  3. public:
  4. Toolbar(const wxString& title);
  5. void OnQuit(wxCommandEvent& event);
  6. wxToolBar *toolbar1;
  7. wxToolBar *toolbar2;
  8. };

toolbars.cpp

  1. #include "toolbars.h"
  2. Toolbar::Toolbar(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title,
  4. wxDefaultPosition, wxSize(300, 250)) {
  5. wxImage::AddHandler(new wxPNGHandler);
  6. wxBitmap exit(wxT("exit.png"), wxBITMAP_TYPE_PNG);
  7. wxBitmap newb(wxT("new.png"), wxBITMAP_TYPE_PNG);
  8. wxBitmap open(wxT("open.png"), wxBITMAP_TYPE_PNG);
  9. wxBitmap save(wxT("save.png"), wxBITMAP_TYPE_PNG);
  10. wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  11. toolbar1 = new wxToolBar(this, wxID_ANY);
  12. toolbar1->AddTool(wxID_ANY, wxT("New"), newb);
  13. toolbar1->AddTool(wxID_ANY, wxT("Open"), open);
  14. toolbar1->AddTool(wxID_ANY, wxT(""), save);
  15. toolbar1->Realize();
  16. toolbar2 = new wxToolBar(this, wxID_ANY);
  17. toolbar2->AddTool(wxID_EXIT, wxT("Exit application"), exit);
  18. toolbar2->Realize();
  19. vbox->Add(toolbar1, 0, wxEXPAND);
  20. vbox->Add(toolbar2, 0, wxEXPAND);
  21. SetSizer(vbox);
  22. Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED,
  23. wxCommandEventHandler(Toolbar::OnQuit));
  24. }
  25. void Toolbar::OnQuit(wxCommandEvent& WXUNUSED(event)) {
  26. Close(true);
  27. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp {
  3. public:
  4. virtual bool OnInit();
  5. };

main.cpp

  1. #include "main.h"
  2. #include "toolbars.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit() {
  5. Toolbar *toolbar = new Toolbar(wxT("Toolbar"));
  6. toolbar->Show(true);
  7. return true;
  8. }

在我们的示例中,我们创建了两个水平工具栏。 我们将它们放置在垂直包装机上。

  1. toolbar1 = new wxToolBar(this, wxID_ANY);
  2. ...
  3. toolbar2 = new wxToolBar(this, wxID_ANY);

在这里,我们创建两个工具栏。

  1. vbox->Add(toolbar1, 0, wxEXPAND);
  2. vbox->Add(toolbar2, 0, wxEXPAND);

在这里,我们将它们添加到垂直框大小调整器中。

wxWidgets 中的菜单和工具栏 - 图4

图:工具栏 s

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