Wxwidgets Event Table / Bind () does not fire, Connect () does

Summary:

After adapting the code in the wxwidgets Hello World tutorial to a "module" in the CppMicroServices structure, events registered with the event table or bindings () are not displayed, but events registered with Connect () do.

i.e. When I click on the menu items, I don't get the popup. If I use the Connect(...)

event handler to register, the popup works.

Why is this happening and how can I fix it?

Environment:

  • Ubuntu 14.04
  • g ++ 4.9
  • wxWidgets 3.0.2
  • biicode 3.0

Code:

Github repository - for full source. It doesn't build easily (ask me to follow the compilation steps if it helps diagnose this).

// The following are excerpts, I haven't included the namespace declarations / #includes

// === BlankDisplayService.cpp === //
// I know the constructor is "heavy", but this is just a spike
// For this issue, this is the entry point
BlankDisplayService::BlankDisplayService() {
    wxApp::SetInstance( new BlankApplication() );
    openWindow(0, nullptr);
}

BlankDisplayService::~BlankDisplayService() {
    wxTheApp->OnExit();
    wxEntryCleanup();
}

int BlankDisplayService::openWindow(int argc, char** argv) {
    wxEntryStart(argc, argv);
    wxTheApp->OnInit();
    wxTheApp->OnRun();
    return 0;
}



// === BlankApplication.cpp === //
bool BlankApplication::OnInit() {
    BlankWindow *window = new BlankWindow( "Hello World", wxPoint(50, 50), wxSize(450, 340));
    window->Show(true);
    return true;
}


// === BlankWindow.h === //
class BlankWindow : public wxFrame {
private:
    wxStaticText *st1;
    wxStaticText *st2;

public:
    enum Command {
        ID_Hello = 1
    };

    BlankWindow(const wxString& title, const wxPoint& pos, const wxSize& size);
    virtual ~BlankWindow();

private:
    void OnMove(wxMoveEvent & event);
    void OnHello(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
    wxDECLARE_EVENT_TABLE();
};


// === BlankWindow.cpp === //

wxBEGIN_EVENT_TABLE(sl::desktop::demo::wx::BlankWindow, wxFrame)
    EVT_MENU(ID_Hello,   BlankWindow::OnHello)
    EVT_MENU(wxID_EXIT,  BlankWindow::OnExit)
    EVT_MENU(wxID_ABOUT, BlankWindow::OnAbout)
wxEND_EVENT_TABLE()

BlankWindow::BlankWindow(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) {
    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", "Help string shown in status bar for this menu item");
    menuFile->AppendSeparator();
    menuFile->Append(wxID_EXIT);
    wxMenu *menuHelp = new wxMenu;
    menuHelp->Append(wxID_ABOUT);
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append( menuFile, "&File" );
    menuBar->Append( menuHelp, "&Help" );
    SetMenuBar( menuBar );
    CreateStatusBar();
    SetStatusText( "Welcome to wxWidgets!" );


    wxPanel* panel = new wxPanel(this, -1);
    panel->SetSize(200, 100);

    st1 = new wxStaticText(panel, -1, wxT(""), wxPoint(10, 10));
    st2 = new wxStaticText(panel, -1, wxT(""), wxPoint(10, 30));

    Connect(wxEVT_MOVE, wxMoveEventHandler(BlankWindow::OnMove));

    Centre();

    //Connect(wxEVT_MENU, wxCommandEventHandler(BlankWindow::OnHello));
}

BlankWindow::~BlankWindow() {
}

void BlankWindow::OnMove(wxMoveEvent& event) {
    wxPoint size = event.GetPosition();
    st1->SetLabel(wxString::Format(wxT("x: %d"), size.x ));
    st2->SetLabel(wxString::Format(wxT("y: %d"), size.y ));
}

void BlankWindow::OnHello(wxCommandEvent& WXUNUSED(event)) {
    wxLogMessage("Hello world from wxWidgets!");
}

void BlankWindow::OnExit(wxCommandEvent& WXUNUSED(event)) {
    Close(true);
}

void BlankWindow::OnAbout(wxCommandEvent& event) {
    wxMessageBox("This is a wxWidgets' Hello world sample", "About Hello World", wxOK | wxICON_INFORMATION );
}

      

Notes:

I use biicode to manage my dependencies, so the imports may not be what you are used to seeing.

I'm pretty sure it all works on the main thread.


Update:

Offsetting the call openWindow(...)

from the BlankDisplayService constructor to the test class triggered events declared using the event table. However, I have not been able to determine why: threadIds are exactly the same, whether they are called from a test or inside a constructor:

If that doesn't work:

[MAIN] Thread Id: 140460630185856
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from SlDesktopDemoWxBundle
[ RUN      ] SlDesktopDemoWxBundle.DisplaysWindow
[TEST] Thread Id: 140460630185856
[CSTR] Thread Id: 140460630185856
[OPEN] Thread Id: 140460630185856
^C

      

When it works:

[CSTR] Thread Id: 139695227554368
[MAIN] Thread Id: 139695227554368
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from SlDesktopDemoWxBundle
[ RUN      ] SlDesktopDemoWxBundle.DisplaysWindow
[TEST] Thread Id: 139695227554368
[OPEN] Thread Id: 139695227554368
[       OK ] SlDesktopDemoWxBundle.DisplaysWindow (3165 ms)
[----------] 1 test from SlDesktopDemoWxBundle (3165 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (3166 ms total)
[  PASSED  ] 1 test.

      

+3


source to share


1 answer


The problem is probably in the initialization code. It's hard to figure out what exactly you are trying to achieve here since you end up calling OnRun()

which is in a normal event loop, why don't you just use the normal pattern?



I also can't see where / how your code exits the event loop. If this happens too quickly, it may explain why you are not receiving events.

0


source







All Articles