wxwidgets自定义事件+调试
发布日期:2021-05-19 23:44:23 浏览次数:6 分类:精选文章

本文共 3226 字,大约阅读时间需要 10 分钟。

自定义事件

大体方法

在 wxWidgets 应用程序中,自定义事件是实现灵活事件处理的关键功能。就像每个事件被其事件类型所唯一确定一样,定义一个自定义事件从为它定义一个新事件类型开始。这通过使用宏来完成。事件类型是可变的,如果有必要它也可以通过使用宏来声明。


使用现有的事件类

如果你仅打算使用 wxCommandEvent 和一个新事件类型,可以使用下面列出的事件表宏之一而不用自己定义一个新事件类。

示例

wxDECLARE_EVENT(MY_EVENT, wxCommandEvent);wxDEFINE_EVENT(MY_EVENT, wxCommandEvent);wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)EVT_MENU(wxID_EXIT, MyFrame::OnExit)EVT_COMMAND(ID_MY_WINDOW, MY_EVENT, MyFrame::OnMyEvent)wxEND_EVENT_TABLE()void MyFrame::OnMyEvent(wxCommandEvent& event){    // 做 something    wxString text = event.GetString();}MyFrame::MyFrame(){    Bind(MY_EVENT, &MyFrame::OnMyEvent, this, ID_MY_WINDOW);}void MyWindow::SendEvent(){    wxCommandEvent event(MY_EVENT, GetId());    event.SetEventObject(this);    event.SetString("Hello");    ProcessWindowEvent(event);}

在上面的代码示例中,我们定义了一个新事件类型 MY_EVENT,并使用 wxCommandEvent 作为事件类。通过宏 wxDECLARE_EVENTwxDEFINE_EVENT,我们完成了事件类型和事件类的结合。如果需要静态事件表绑定,可以使用 EVT_COMMAND 宏进行映射。


定义你自己的事件类

在某些环境下,你必须定义你自己的事件类,例如从一个地方发送一些很复杂的数据到另一个地方。除了定义你的事件类,如果你打算事件表来处理这种类型的事件,你还需要定义你自己的事件表宏。

示例

class MyPlotEvent : public wxEvent{public:    MyPlotEvent(wxEventType eventType, int winid, const wxPoint& pos)        : wxEvent(winid, eventType), m_pos(pos)    {}    wxPoint GetPoint() const { return m_pos; }    virtual wxEvent* Clone() const { return new MyPlotEvent(*this); }    unsigned char* GetPointer() const { return m_ptr; }    private:    const wxPoint m_pos;    unsigned char* m_ptr;};#define MY_EVT_PLOT_CLICK(id, func)    wx__DECLARE_EVT1(MY_PLOT_CLICKED, id, MyPlotEventHandler(func))wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)EVT_PLOT(ID_MY_WINDOW, MyFrame::OnPlot)wxEND_EVENT_TABLE()void MyFrame::OnPlot(MyPlotEvent& event){    // 执行什么操作    wxString text = event.GetPoint().y.ToString();}MyFrame::MyFrame(){    Bind(MY_PLOT_CLICKED, &MyFrame::OnPlot, this, ID_MY_WINDOW);}void MyFrame::SendEvent(){    MyPlotEvent event(MY_PLOT_CLICKED, GetId(), wxPoint(100, 200));    event.SetEventObject(this);    ProcessWindowEvent(event);}

事件的产生与处理

在定义好事件类后,有以下几个关键函数可选:

  • QueueEvent:将事件加入队列以便进行后续处理。
  • PostEvent:立即发送事件到指定的目标对象。
  • 这些函数对于事件的跨线程传递尤其重要。例如:

    跨线程事件传递

    假设你需要在主线程和工作线程之间传递事件:

    class MyThreadEvent : public wxThreadEvent{public:    MyThreadEvent(wxEventType type, int winid, const unsigned char* data)        : wxThreadEvent(winid, type)        , m_data(data)    {}    ~MyThreadEvent()    {        delete m_data;    }        const unsigned char* GetPointer() const    {        return m_data;    }    private:    const unsigned char* m_data;  // 其他成员可根据需要添加};#define EVT_POINTER_ARR(id, func)  \    wx__DECLARE_EVT1(WX_POINTER_ARR, id, MyPlotEventHandler(func))

    事件表配置

    在头文件中定义事件类型:

    wxDECLARE_EVENT(WX_POINTER_ARR, MyThreadEvent);wxDEFINE_EVENT(WX_POINTER_ARR, MyThreadEvent);wxBEGIN_EVENT_TABLE(showpic, wxFrame)    EVT_POINTER_ARR(wxID_ANY, showpic::OnProcessThreadEvent)wxEND_EVENT_TABLE();void showpic::OnProcessThreadEvent(MyThreadEvent& event){    wxImage image(col, row, event.GetPointer());    bitmap = wxBitmap(image.Scale(800, 600));    Refresh();}showpic::showpic(){    // 绑定事件处理函数}void showpic::SendEvent(){    wxQueueEvent(hwnd, new MyThreadEvent(WX_POINTER_ARR, wxID_ANY, new unsigned char[m_plot_width * m_plot_height]()));}

    上面的示例展示了如何定义一个自定义事件类并与事件表绑定。需要注意的是,事件对象的所有权应由发送方掌握,避免共享问题。

    上一篇:wxwidgets编写多线程程序--wxThread
    下一篇:多级菜单框架(C实现)

    发表评论

    最新留言

    路过按个爪印,很不错,赞一个!
    [***.219.124.196]2025年05月05日 16时17分05秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章