从wxEvtHandler回调派生类永远不会被调用

时间:2017-02-24 20:26:19

标签: c++ wxwidgets

我有一个派生自wxEvtHandler的类。它创建一个按钮并绑定一个“click”回调。这个回调永远不会被调用。如果我在wxFrame中创建相同的按钮,一切正常。我错过了什么吗?提前谢谢。

#include <wx/wx.h>

const int ID1 = 1;
const int ID2 = 2;

struct Derived : public wxEvtHandler
{
    Derived(wxFrame* frame)
    {
        auto btn = new wxButton(frame, ID1, "A", wxPoint(10, 20));
        Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Derived::Click, this, ID1);
    }

    void Click(wxCommandEvent& ev)
    {
        auto dial = new wxMessageDialog(0, "Button B does not works fine!", "", wxOK);
        dial->ShowModal();
    }
};

struct MainFrame : public wxFrame
{
    MainFrame() : wxFrame(NULL, wxID_ANY, "")
    {
        auto pane = new Derived(this);

        auto btn = new wxButton(this, ID2, "B", wxPoint(10, 50));
        Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MainFrame::Click, this, ID2);

    }

    void Click(wxCommandEvent& ev)
    {
        auto dial = new wxMessageDialog(0, "Button B works fine!", "", wxOK);
        dial->ShowModal();
    }
};

struct Application : public wxApp
{
    virtual bool OnInit()
    {
        auto simple = new MainFrame();
        simple->Show(true);
        return true;
    }
};

IMPLEMENT_APP(Application)

1 个答案:

答案 0 :(得分:1)

使用 btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Derived::Click, this, ID1);

基本原理是这样的:当按钮想要处理click事件时,它调用GetEventHandler()来查找绑定的处理程序(代码中的Click())。但GetEventHandler()返回其父(wxFrame)事件处理程序,该处理程序绑定“Click”。所以什么都不做。

在调用btn->SetEventHandler(this);之前使用btn->PushEventHandler(this);Bind()将Derived设置为处理程序会使GetEventHandler()返回具有Click处理程序的Derived,然后事件被处理。
但随后会出现另一个问题:当删除按钮时,必须先弹出所有的事件处理程序(否则某些待处理事件可能会保留悬空删除的指针)。此问题会强制您在删除按钮时调用PopEventHandler() ...忘记所有这些并使用btn->Bind(...)