wxWidgets的单双击事件过滤

wxWidgets的控件,在双击时,也会同时触发单击事件,而且是触发两次LEFT_UP事件。

如果一个控件同时绑定单击和双击事件的时候,就会对我们的控制造成混乱。

一般解决这个问题有两个方法。

方法1:使用定时器,延时触发单击事件

wxWidgets中可以使用wxTimer来延时。当单击时先阻止事件被处理,并启动计时器。在超时之前如果有双击事件触发 ,则停止单击事件。否则继续处理单击事件。

这种方法会使得代码的程序控制变得麻烦,而且 wxTimer的使用也会增加不必要的耗费。

方法2:使用事件循环,过滤单击。

这也是本文着重讨论使用的方法。

具体步骤是:

1.LEFT_UP事件触发后,先处理后面的事件。

2.如果后面的这些事件中有双击事件,则将LEFT_UP事件屏蔽

3.如果后面的这些事件处理都没有双击事件,且时间超过200ms,才处理LEFT_UP事件

 MFC也有类似的问题:MFC 处理双击事件时屏蔽掉单击事件-CSDN博客

不过wxWidgets没有PeekMessage,TranslateMessage,DispatchMessage等API,所以没法直接使用MFC的解决方案。

wxWidgets也是有事件循环的,那就是wxGUIEventLoop。

首先让wxWidgets的控件子类增加一个成员 wxGUIEventLoop m_loop;

再增加一个wxLongLong m_lastDbClick记录上次双击的点击时间

然后重写 ProcessEvent 方法。在其中判断事件:

bool MyFrame::ProcessEvent(wxEvent& event) {
    int type = event.GetEventType();
    wxLongLong begin_time = wxGetLocalTimeMillis();
    if (wxEVT_LEFT_UP==type) {
        const int span = 500;
        wxLongLong duration = 0;
        wxLongLong cur_time;
        wxLongLong end_loop_time = begin_time + span;
        do {
            //先把后面的事件处理了
            m_loop.DispatchTimeout(50);
            cur_time = wxGetLocalTimeMillis();
            duration = cur_time - m_lastDbClick;
            if (duration < span) {
                //如果期间触发了双击事件,则终止事件。
                wxLogDebug("%s:duration:%s,stop left up event", cur_time.ToString(), duration.ToString());
                return false;
            }
        } while (cur_time< end_loop_time);//在span时间内循环
    }
    else if (wxEVT_LEFT_DCLICK == type) {
        wxLogDebug("%s:process double click event", begin_time.ToString());
        //刷新上次双击事件的时间
        m_lastDbClick = wxGetLocalTimeMillis();
    }
    return wxFrame::ProcessEvent(event);
}

只要这样,就可以解决wxWidget中单双击事件重叠的问题了。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
wxWidgets中,我们可以通过继承wxTaskBarIcon类来处理任务栏按钮的事件。下面是一个示例代码,演示了如何使用wxWidgets处理任务栏按钮的点击事件: ```cpp #include <wx/wx.h> class MyTaskBarIcon : public wxTaskBarIcon { public: MyTaskBarIcon() { // 在构造函数中添加任务栏按钮 SetIcon(wxICON(wxLOGO), "My TaskBar Icon"); } void OnLeftButtonDClick(wxTaskBarIconEvent& event) { // 处理任务栏按钮的双击事件 wxMessageBox("TaskBar Icon Double Clicked!"); } void OnMenuOpen(wxCommandEvent& event) { // 处理任务栏按钮的右键菜打开事件 wxMessageBox("TaskBar Icon Menu Opened!"); } wxMenu* CreatePopupMenu() { // 创建任务栏按钮的右键菜 wxMenu* menu = new wxMenu; menu->Append(wxID_OPEN, "Open"); menu->Append(wxID_CLOSE, "Close"); return menu; } wxDECLARE_EVENT_TABLE(); }; wxBEGIN_EVENT_TABLE(MyTaskBarIcon, wxTaskBarIcon) EVT_TASKBAR_LEFT_DCLICK(MyTaskBarIcon::OnLeftButtonDClick) EVT_MENU(wxID_OPEN, MyTaskBarIcon::OnMenuOpen) EVT_MENU(wxID_CLOSE, MyTaskBarIcon::OnMenuClose) wxEND_EVENT_TABLE() class MyApp : public wxApp { public: bool OnInit() { // 创建应用程序的主窗口 wxFrame* frame = new wxFrame(NULL, wxID_ANY, "My App"); frame->Show(); // 创建任务栏按钮 MyTaskBarIcon* taskBarIcon = new MyTaskBarIcon; taskBarIcon->SetIcon(wxICON(wxLOGO), "My TaskBar Icon"); return true; } }; wxIMPLEMENT_APP(MyApp); ``` 在上面的代码中,我们首先创建了一个自定义的MyTaskBarIcon类,继承自wxTaskBarIcon类。在构造函数中,我们使用SetIcon()函数添加了一个任务栏按钮。然后,我们重写了OnLeftButtonDClick()函数和CreatePopupMenu()函数来处理任务栏按钮的双击事件和右键菜打开事件。最后,我们使用宏定义wxDECLARE_EVENT_TABLE()和wxBEGIN_EVENT_TABLE()来声明和定义事件表,将事件与相应的处理函数关联起来。 在应用程序的主函数中,我们创建了一个主窗口,并创建了一个MyTaskBarIcon对象来添加任务栏按钮。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值