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的響應判斷方式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM