【问题标题】:Creating a handler function with Bind to handle clicked menu item - wxWidgets 3.0使用 Bind 创建处理程序函数以处理单击的菜单项 - wxWidgets 3.0
【发布时间】:2014-07-14 02:26:08
【问题描述】:

我想知道如何使用 Bind 函数在 wxWidgets 3.0 , C++ 中创建一个简单的事件处理程序。

为了开始我的实验,我创建了一个非常简单的应用程序 - 一个带有菜单的主框架和菜单中的几个项目。到目前为止没有任何问题,一切都按预期出现。我使用的部分代码是:

//create a menu bar
wxMenuBar* mbar = new wxMenuBar();

wxMenu* fileMenu = new wxMenu(_T(""));

fileMenu->Append(item1, _("&Item_1"), _("Select item 1"));
mbar->Append(fileMenu, _("&File"));


现在我想使用 Bind 创建一个简单的处理程序,当从菜单中选择 Item_1 时会弹出一个消息框,例如:

wxMessageBox( "You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION );


请注意,弹出消息框只是我选择的一个简单示例,以快速掌握概念并查看结果。如果可能,我希望 Bind 事件处理程序尽可能通用,用于任意事件和操作。

【问题讨论】:

    标签: c++ events menu wxwidgets menuitem


    【解决方案1】:
    #include <wx/wx.h>
    #define item1 (wxID_HIGHEST + 1)
    
    class CApp : public wxApp
    {
    public:
        bool OnInit() {
            // Create the main frame.
            wxFrame * frame = new wxFrame(NULL, wxID_ANY, "demo");
            // Create a menu bar.
            wxMenuBar* mbar = new wxMenuBar();
            wxMenu* fileMenu = new wxMenu(_T(""));
            fileMenu->Append(item1, _("&Item_1"), _("Select item 1"));
            mbar->Append(fileMenu, _("&File"));
            frame->SetMenuBar(mbar);
            // Bind an event handling method.
    #if __cplusplus < 201103L
            frame->Bind(wxEVT_MENU, &CApp::item1_OnMenu, this, item1);
    #else
            frame->Bind(wxEVT_MENU, [](wxCommandEvent & evt)->void{
                wxMessageBox("You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION);
            }, item1);
    #endif
            // Enter the message loop.
            frame->Show(true);
            return this->wxApp::OnInit();
        }
    #if __cplusplus < 201103L
    protected:
        void item1_OnMenu(wxCommandEvent & evt) {
            wxMessageBox("You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION);
        }
    #endif
    };
    DECLARE_APP(CApp)
    IMPLEMENT_APP(CApp)
    

    wxEvtHandler::Bind 方法有 3 个重载。以上仅演示了其中的 2 个。

    对于可用的事件类型,将是Bind 的第一个参数,请参阅wx/event.h。 event.h 还告诉我们应该使用哪个事件类。例如,

    #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
    

    注意wxCommandEventHandler,去掉后缀Handler,剩下的就是事件类wxCommandEvent

    【讨论】:

    • 谢谢你的回答,写的很好。这个话题让我很困惑,即使你的回答和我选择的一个简单的例子也是如此。我还不了解事件以及某些声明的含义(Bind 中的 wxEVT_MENU,或处理函数中的 evt,...)。当我遇到更复杂的控件和小部件时,想想该怎么做是相当可怕的 =))
    • 长话短说,当 wxWidgets 需要为 wxEvent 对象寻找“事件处理方法/函数”时,它会逐一检查 wxEvtHandler 对象的“事件处理程序链”中的项一。一个事件处理程序链由一个或多个 wxEvtHandler 对象组成。每个 wxEvtHandler 对象都有一个“(每实例)动态事件表”和“静态(每类)事件表”。将首先检查动态事件表。 Bind 所做的就是在动态事件表中添加一个条目。
    • 顺便说一句,所有 wxEvent 对象都经过 wxAppConsole::HandleEvent。因此,在方法中添加断点并单步执行可能会帮助您了解框架的工作原理。
    • 你的例子对我来说效果很好。但我对菜单中的退出按钮有疑问。我无法让它真正退出应用程序。您能否添加评论或扩展您的答案以向我解释如何做到这一点?谢谢。
    • 上例中没有“退出”菜单项。如果要关闭主框架,需要调用继承自wxWindow的方法Close,该方法将事件类型wxEVT_CLOSE_WINDOW发送到主框架本身的事件处理链中,其中处理方法为@987654331 @ 默认情况下,OnCloseWindow 的默认行为是Destroy 本身。 Destroy 对主框架的意义是让 wxWidgets 决定何时真正 delete 它,通常在相关事件队列为空之后。
    猜你喜欢
    • 2014-09-12
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2017-07-29
    相关资源
    最近更新 更多