简体   繁体   中英

Can somebody help me with EventHandling on WXWidgets

while trying to make some first progress with WXWidgets in C++ I´ve got on a problem.

As youre able to see in the Code below, I´m trying to Handle an Button-Click-Event from an WXWidget-Application.

The main Problem is that the dedicated Method TopPanel::OnClick() doesnt run. (Nothing is print to console)

Possible Errors:

  • Problem with my implementation of PanelEvents
  • Wrongly installed WXWidgets (probably not cuz it does compile without any errors)
#include <wx/wx.h>

class App : public wxApp
{
public:
    virtual bool OnInit();
};

class MainFrame : public wxFrame
{
public:
    MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
};

class TopPanel : public wxPanel
{
public:
    TopPanel(wxWindow* parent, wxSize size);
private:
    void OnClick(wxCommandEvent &);
    wxDECLARE_EVENT_TABLE();
};

enum ButtonID {
    button_id_first = wxID_LAST + 1,
    button_id_other
};

bool App::OnInit()
{
    MainFrame* frame = new MainFrame("Nova Loader", wxDefaultPosition, wxDefaultSize);
    frame->Show(true);
    return true;
}

wxIMPLEMENT_APP(App);

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
    this->SetBackgroundColour(wxColor(25, 25, 25));
    this->SetFocus();

    TopPanel* pnl_top = new TopPanel(this, wxSize(500, 30));
    wxPanel* pnl_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(500, 270));
    wxButton* btn_load = new wxButton(pnl_top, button_id_first, "Load");
    wxButton* btn_exit = new wxButton(pnl_top, button_id_other, "Exit");
    wxBoxSizer* s1 = new wxBoxSizer(wxVERTICAL);
    s1->Add(pnl_top, 0, wxALL, 5);
    s1->Add(pnl_bottom, 1, wxALL, 5);

    wxBoxSizer* s2 = new wxBoxSizer(wxHORIZONTAL);
    s2->Add(btn_load, 0, wxRIGHT, 5);
    s2->Add(btn_exit, 0);

    wxBoxSizer* s3 = new wxBoxSizer(wxVERTICAL);
    s3->Add(s2, 0, wxALIGN_RIGHT | wxRIGHT | wxTOP, 3);

    pnl_top->SetSizer(s3);
    pnl_bottom->SetBackgroundColour(wxColor(45, 45, 45));

    this->SetSizerAndFit(s1);
}

TopPanel::TopPanel(wxWindow* parent, wxSize size) : wxPanel(parent, wxID_ANY, wxDefaultPosition, size)
{
    this->SetSize(500, 30);
    this->SetId(wxID_ANY);
    this->SetBackgroundColour(wxColor(45, 45, 45));
}

void TopPanel::OnClick(wxCommandEvent &e)
{
    std::cout << e.GetId() << std::endl;
}

wxBEGIN_EVENT_TABLE(TopPanel, wxPanel)
EVT_BUTTON(button_id_first, TopPanel::OnClick)
EVT_BUTTON(button_id_other, TopPanel::OnClick)
wxEND_EVENT_TABLE()

Thanks to everyone trying to help me!

~ Tim

First things first, your given example successfully calls the OnClick method. So your claim that OnClick is not called is not correct.

Now that being said, with newer(modern) wxWidgets you can also use dynamic event table using Bind instead of static event table as shown below. The changes made are highlighted as comments in the below given program:

class TopPanel : public wxPanel
{
public:
    TopPanel(wxWindow* parent, wxSize size);
    void OnClick(wxCommandEvent &);
    //removed wxdeclare_event_table from here as no longer needed 
};
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
    //other code as before
//---------------------------------------------vvvvvvvv----------->let wxwidgets choose the id for you 
    wxButton* btn_load = new wxButton(pnl_top, wxID_ANY, "Load");
    //bind btn_load to onClick 
    btn_load->Bind(wxEVT_BUTTON, &TopPanel::OnClick, pnl_top);
//---------------------------------------------vvvvvvvv------------>let wxwidgets choose the id for you
    wxButton* btn_exit = new wxButton(pnl_top, wxID_ANY, "Exit");
    //bind btn_exit to onclick 
    btn_exit->Bind(wxEVT_BUTTON, &TopPanel::OnClick, pnl_top);
    //other code as before
}

Below is the complete working example that uses Bind :

#include <wx/wx.h>

class App : public wxApp
{
public:
    virtual bool OnInit();
};

class MainFrame : public wxFrame
{
public:
    MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
};

class TopPanel : public wxPanel
{
public:
    TopPanel(wxWindow* parent, wxSize size);
    void OnClick(wxCommandEvent &);
    //removed wxdeclare_event_table from here as no longer needed 
};

enum ButtonID {
    button_id_first = wxID_LAST + 1,
    button_id_other
};

bool App::OnInit()
{
    MainFrame* frame = new MainFrame("Nova Loader", wxDefaultPosition, wxDefaultSize);
    frame->Show(true);
    return true;
}

wxIMPLEMENT_APP(App);

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
    this->SetBackgroundColour(wxColor(25, 25, 25));
    this->SetFocus();

    TopPanel* pnl_top = new TopPanel(this, wxSize(500, 30));
    wxPanel* pnl_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(500, 270));
//---------------------------------------------vvvvvvvv----------->let wxwidgets choose the id for you 
    wxButton* btn_load = new wxButton(pnl_top, wxID_ANY, "Load");
    //bind btn_load to onClick 
    btn_load->Bind(wxEVT_BUTTON, &TopPanel::OnClick, pnl_top);
    wxButton* btn_exit = new wxButton(pnl_top, wxID_ANY, "Exit");
    //bind btn_exit to onclick 
    btn_exit->Bind(wxEVT_BUTTON, &TopPanel::OnClick, pnl_top);
    wxBoxSizer* s1 = new wxBoxSizer(wxVERTICAL);
    s1->Add(pnl_top, 0, wxALL, 5);
    s1->Add(pnl_bottom, 1, wxALL, 5);

    wxBoxSizer* s2 = new wxBoxSizer(wxHORIZONTAL);
    s2->Add(btn_load, 0, wxRIGHT, 5);
    s2->Add(btn_exit, 0);

    wxBoxSizer* s3 = new wxBoxSizer(wxVERTICAL);
    s3->Add(s2, 0, wxALIGN_RIGHT | wxRIGHT | wxTOP, 3);

    pnl_top->SetSizer(s3);
    pnl_bottom->SetBackgroundColour(wxColor(45, 45, 45));

    this->SetSizerAndFit(s1);
}

TopPanel::TopPanel(wxWindow* parent, wxSize size) : wxPanel(parent, wxID_ANY, wxDefaultPosition, size)
{
    this->SetSize(500, 30);
    this->SetId(wxID_ANY);
    this->SetBackgroundColour(wxColor(45, 45, 45));
}

void TopPanel::OnClick(wxCommandEvent &e)
{
    std::cout << e.GetId() << std::endl;
    std::cout<<"toppanel onclick called"<<std::endl;
}
//no need for event table entries here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM