2015-04-19 1 views
3

Резюме:WxWidgets Event Table/Bind() события, кажется, не стрелять, Connect() делает

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

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

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

Окружающая среда:

  • Ubuntu 14,04
  • г ++ 4,9
  • WxWidgets 3.0.2
  • Биикод 3,0

Код:

Github repository - для получения полного источника. Он не строится легко (попросите меня выполнить шаги компиляции, если это поможет диагностировать это).

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

Примечание:

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

Уверен, что все это работает в основной теме.


Update:

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

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

[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. 
+1

У меня нет опыта работы с wxWidgets, но, возможно, ваша проблема связана со статическими проблемами порядка инициализации.Если ваш 'BlankDisplayService' создан в методе' Activator :: Load() 'вашего модуля CppMicroServices, этот код выполняется во время статической инициализации вашего модуля. Если вы звоните во внешние библиотеки, эти вызовы могут быть небезопасными в данный момент времени. – Sascha

+0

Я думаю, что так происходит, спасибо – Azriel

ответ

0

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

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

+0

Под «нормальным шаблоном» вы имеете в виду использование одного из макросов для запуска приложения? Ограничение: у меня есть wxwidgets, который должен жить в модуле CppMicroServices, что означает, что он не содержит основную точку входа. Код не выходит из цикла событий; Я просто проверял, как я буду пытаться запускать wxwidgets в качестве модуля и не потерять никаких намеченных функций. – Azriel

+0

Если вы можете ввести основной цикл, вы должны просто использовать 'wxIMPLEMENT_APP()' как обычно, а затем вызывать 'wxEntry()' из любой точки входа, которую вы определяете, это не должно быть 'main()'. –