首页 > 解决方案 > wxTimer 与 Bind() 绑定后未调用回调

问题描述

我想在我的应用程序中使用 wxTimer,但我不想使用预处理器宏来绑定事件。相反,我想Bind()在 CTOR 调用期间使用将事件绑定到我的 ui 元素。
绑定我的计时器后,它不启动或不调用事件处理程序。据此,应该像我想要的那样工作。我也不想用Connect()。以同样的方式绑定一个按钮就可以了。这是一个最小的例子:

最小示例:

#include <wx/wx.h>
#include <iostream>

class MainFrame : public wxFrame
{
private:
    const int DELTA_TIME = 100; // time between timer events (in ms)
private:
    wxTimer* timer = nullptr;
    void OnTimer(wxTimerEvent& evt);
    void OnButtonClick(wxCommandEvent& evt);
public:
    MainFrame();
    virtual ~MainFrame();
};

void MainFrame::OnTimer(wxTimerEvent& evt)
{
    std::cout << "Timer Event!" << std::endl; // never happens
}

void MainFrame::OnButtonClick(wxCommandEvent& evt)
{
    std::cout << "Button Event!" << std::endl; // works just fine
}

MainFrame::MainFrame()
    : wxFrame(nullptr, wxID_ANY, "Test", wxPoint(0, 0), wxSize(600, 400))
{
    timer = new wxTimer(this, wxID_ANY);
    timer->Bind(
        wxEVT_TIMER,                    // evt type
        &MainFrame::OnTimer,            // callback
        this,                           // parent
        timer->GetId()                  // id
    );
    timer->Start(DELTA_TIME, wxTIMER_CONTINUOUS);

    wxButton* testBtn = new wxButton(this, wxID_ANY, "Test", wxPoint(20, 20));
    testBtn->Bind(wxEVT_BUTTON, &MainFrame::OnButtonClick, this);
}

MainFrame::~MainFrame()
{
    if (timer->IsRunning())
    {
        timer->Stop();
    }
}

// application class
class Main : public wxApp
{
public:
    virtual bool OnInit();
};

IMPLEMENT_APP(Main)

bool Main::OnInit()
{
    MainFrame* mainFrame = new MainFrame();
    SetTopWindow(mainFrame);
    mainFrame->Show();
    return true;
}

标签: c++callbackwxwidgets

解决方案


你应该改变

timer->Bind(...

只是

Bind(...

该行将timer = new wxTimer(this, wxID_ANY);主框架设置为计时器的所有者,因此这是触发计时器时通知的项目。但是,该行timer->Bind(...设置计时器以处理计时器事件。但是事件不会发送到计时器,而是发送到主框架。因此有必要将主框架设置为事件处理程序,这就是上面给出的更改所做的。


推荐阅读