zoukankan      html  css  js  c++  java
  • Qt:QPushButton 单击、双击响应区分

    开发环境:win10+vs2015+qt5.9.1

    背景:QPushButton的双击事件虽然一直有,但是在双击完成之前,总会响应到单击的事件处理或者连接槽,使用很不方便。自己子类化了一个QPushButton来区分这两种点击事件的处理

     1 /*
     2 * Description: 分开响应单击和双击的QPushButton
     3 * Author: 公子开明 KaiMing Prince
     4 * Detail: 默认的QPushButton,双击事件触发前会先触发单击事件,影响两个操作的分别处理
     5 * Class: DoubleClickedButton
     6 * Implement: 本类实现了QPushButton双击和单击的分别处理事件
     7 */
     8 #ifndef _DOUBLE_CLICKED_BUTTON_H__
     9 #define _DOUBLE_CLICKED_BUTTON_H__
    10 #include <QPushButton>
    11 
    12 class QTimer;
    13 
    14 class DoubleClickedButton : public QPushButton
    15 {
    16     Q_OBJECT
    17 
    18 public:
    19     DoubleClickedButton(QWidget *parent=Q_NULLPTR);
    20     DoubleClickedButton(const QString &text, QWidget *parent = Q_NULLPTR);
    21     DoubleClickedButton(const QIcon &icon, const QString &text, QWidget *parent = Q_NULLPTR);
    22 
    23     ~DoubleClickedButton();
    24 
    25 protected:
    26     virtual bool event(QEvent* event);
    27 
    28 signals:
    29     void singleClicked();
    30     void doubleClicked();
    31 
    32 private:
    33     bool              m_bDoubleClicked;
    34     QTimer*            m_single_clicked_timer;
    35 };
    36 #endif //_DOUBLE_CLICKED_BUTTON_H__

    首先,我们需要一个定时器来延时判断单击事件,当收到单击事件是启动定时器;当定时器触发还没有第二次单击进入的时候,认为是单击事件;触发之前收到双击事件或第二次单击事件,则视为是一个双击动作,具体代码如下

     1 #include "DoubleClickedButton.h"
     2 #include <QEvent>
     3 #include <QTimer>
     4 
     5 DoubleClickedButton::DoubleClickedButton(QWidget *parent)
     6     : QPushButton(parent),
     7       m_single_clicked_timer(new QTimer(this)),
     8       m_bDoubleClicked(false)
     9 {
    10     m_single_clicked_timer->setSingleShot(true);
    11     connect(m_single_clicked_timer, SIGNAL(timeout()), this, SIGNAL(singleClicked()));
    12 }
    13 
    14 DoubleClickedButton::DoubleClickedButton(const QString &text, QWidget *parent)
    15     : DoubleClickedButton(parent)
    16 {
    17     setText(text);
    18 }
    19 
    20 DoubleClickedButton::DoubleClickedButton(const QIcon &icon, const QString &text, QWidget *parent)
    21     : DoubleClickedButton(text, parent)
    22 {
    23     setIcon(icon);
    24 }
    25 
    26 DoubleClickedButton::~DoubleClickedButton()
    27 {
    28 }
    29 
    30 bool DoubleClickedButton::event(QEvent* event)
    31 {
    32     switch (event->type())
    33     {
    34     case QEvent::MouseButtonRelease:
    35         m_bDoubleClicked ? m_bDoubleClicked = false//如果是第二次进入,重置状态
    36             /*这里需要一个超时判断,超时还没进入MouseButtonDblClick事件才算是单击效果*/
    37             : m_single_clicked_timer->start(10);//测试发现间隔时间最好不要低于10ms,否则不够两个事件的反馈间隔,如果需要延迟,可以自行修改间隔时间
    38         break;
    39     case QEvent::MouseButtonDblClick:
    40         m_single_clicked_timer->stop();//进入双击事件停止掉定时器
    41         m_bDoubleClicked = true;
    42         emit doubleClicked();
    43         break;
    44     default:
    45         break;
    46     }
    47 
    48     return QPushButton::event(event);
    49 }

    定时器只能触发一次,否则会无限发出单击信号,这里要注意一下;在mouseRelease事件中,判断是否已经触发过doubleclick,如果触发过就不能再启动定时器了,只有第一次单击才能触发定时器,所以我们需要一个bool值判断一下是否为第二次进入单击事件。

    剩下的就很简单了,双击事件直接关闭定时器,发送出双击信号,单击事件则等待定时器触发认为没有第二次点击再发出单击信号

    定时器的时间在测试中发现最好不要低于10ms,至于具体doubleclick和第二次mouseRelease到底差了多少响应间隔,我没有具体去打印判断了,有兴趣的可以自己测试,或者参考qt源码看doubleclick的响应判断方式

  • 相关阅读:
    socket
    IPv4 IPv6
    2变量与基本类型之const限定符
    15面向对象程序设计
    深度探索C++对象模型之第三章:数据语义学
    线段树(成段更新) 之 poj 3468 A Simple Problem with Integers
    USACO 之 Section 1.1 Ad Hoc Problems (已解决)
    构造字符串 之 hdu 4850 Wow! Such String!
    模拟 + 最短路 之 hdu 4849 Wow! Such City!
    简单题(需要注意一个细节) 之 hdu 4847 Wow! Such Doge!
  • 原文地址:https://www.cnblogs.com/KaiMing-Prince/p/7601681.html
Copyright © 2011-2022 走看看