События таблицы событий wxwidgets / Bind () не появляются, Connect () делает

Резюме:

После адаптации кода в wxwidgets учебник Hello World в «модуле» в платформе CppMicroServices события, зарегистрированные с помощью таблицы событий или Bind (), по-видимому, не запускаются, а события, зарегистрированные с помощью Connect (), запускаются.

т.е. когда я нажимаю на пункты меню, я не получаю всплывающее окно. Если я использую Connect(...) чтобы зарегистрировать обработчик событий, всплывающее окно работает.

Почему это происходит, и как я могу это исправить?

Среда:

  • Убунту 14.04
  • g ++ 4.9
  • wxWidgets 3.0.2
  • биокод 3.0

Код:

Github хранилище — для полного источника. Это не легко собрать (спросите меня о шагах компиляции, если это поможет диагностировать это).

// 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 );
}

Заметки:

Я использую biicode для управления своими зависимостями, поэтому импорт может не соответствовать тому, что вы привыкли видеть.

Я уверен, что все это работает в основном потоке.


Обновить:

Перенести openWindow(...) вызов из конструктора BlankDisplayService в тестовый класс вызвал события, объявленные с использованием таблицы событий, для корректного запуска. Однако я не смог определить, почему — идентификаторы потоков одинаковы независимо от того, вызывается ли он из теста или из конструктора:

Когда это не работает:

[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

Когда это работает:

[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

Решение

Проблема, вероятно, в вашем коде инициализации. Трудно понять, чего именно ты здесь пытаешься достичь, так как в итоге ты звонишь OnRun(), который все равно входит в нормальный цикл событий, почему бы вам просто не использовать обычный шаблон?

Я также не вижу, где / как ваш код выходит из цикла обработки событий. Если это произойдет слишком рано, это может объяснить, почему вы не получаете события.

0

Другие решения