Qt实现鼠标双击事件

当同一个部件既要响应鼠标单击事件又要响应鼠标双击事件时,就会发生冲突,如下例:

创建自己的按钮类,让其继承于QPushButton类(特别注意!!!),在创建类的时候默认可供选择的基类中无QPushButton类且没有QPushButton类的基类,无法使用多重继承,故必须手动修改继承。之后声明所具备的信号以及信号的发送条件,头文件里面代码如下:

#ifndef MYBTN_H
#define MYBTN_H

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>

class Mybtn :  public QPushButton
{
    Q_OBJECT
public:
    explicit Mybtn(QWidget *parent = nullptr);
    //重写父类的两个虚函数
    virtual void mouseDoubleClickEvent(QMouseEvent *event) {
        if(event->button() == Qt::LeftButton) {
            emit doubleClicked();
        }
    }
    virtual void mousePressEvent(QMouseEvent *event) {
        if(event->button() == Qt::LeftButton) {
            emit mousePress();
        }
    }
signals:
    void doubleClicked();
    void mousePress();
};

#endif // MYBTN_H

在源文件中实现按钮的构造函数,此类的析构函数采用系统默认提供,故不声明,源文件里面代码如下:

#include "mybtn.h"
#include <QString>
#include <QPushButton>
#include <QDebug>

Mybtn::Mybtn(QWidget *parent)
    :QPushButton{parent}
{
    this->setParent(parent);
    this->setText("我是自定义按钮");
    this->setFixedSize(QSize(100, 50));
}

之后在widget中实例化一个按钮对象,并使用连接函数(connect函数用法此处不赘述)实现鼠标单击事件与鼠标双击事件,widget源文件代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include "mybtn.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    Mybtn *btn = new Mybtn(this);
    btn->move(100,200);
    connect(btn,&Mybtn::mousePress,this,&Widget::close);
    connect(btn,&Mybtn::doubleClicked,this,&Widget::close);
}

Widget::~Widget()
{
    delete ui;
}

运行之后发现了在文章开头提到的问题,在单击鼠标之后,connect函数就会触发,从而关闭界面, 与鼠标双击事件冲突。解决方法:添加一个计时器,在规定时间内要是只单击一次就是鼠标单击事件,否则为鼠标双击事件。创建自定义按钮类的操作和前文所述相近,不再过多赘述,头文件代码如下:

#ifndef MYBTN_H
#define MYBTN_H

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>
#include <QTimer>
#include "mybtn.h"

class Mybtn : public QPushButton
{
    Q_OBJECT
public:
    explicit Mybtn(QWidget *parent = nullptr);
    void mousePressEvent(QMouseEvent *)override; //重写函数
signals:

private slots:
    void slotClickTime();

private:
    QTimer* _clickTimer = nullptr;//使用定时器来判断鼠标单击还是双击
    int _clickCount = 0;//点击次数
};

#endif // MYBTN_H

自定义按钮类源文件如下:

#include "mybtn.h"
#include <QString>
#include <QPushButton>
#include <QDebug>
#include <QTimer>

Mybtn::Mybtn(QWidget *parent)
    : QPushButton{parent}//构造函数的调用
{
    _clickTimer = new QTimer;
    connect(_clickTimer, SIGNAL(timeout()), this, SLOT(slotClickTime()));
    this->setParent(parent);
    this->setText("我是自定义按钮");
    this->setFixedSize(QSize(100, 50));
}
//头文件中声明的重写函数在此实现
void Mybtn::mousePressEvent(QMouseEvent *e) {
    if (e->button() & Qt::LeftButton) {
        if (!_clickTimer->isActive()) {
            _clickTimer->start(300);
            _clickCount++;
        } else {
            _clickCount++;
        }
    }
}

void Mybtn::slotClickTime() {
    _clickTimer->stop();
    if (_clickCount == 1) {//只点击了一次
        qDebug() << QStringLiteral("鼠标左键点击了一次");
    } else if (_clickCount == 2) {//双击鼠标
        qDebug() << QStringLiteral("鼠标左键点击了两次");
    }
    _clickCount = 0;
}

widget的源文件如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include "mybtn.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    Mybtn *btn = new Mybtn(this);
    btn->move(100,200);
}

Widget::~Widget()
{
    delete ui;
}

最后运行结果可以监测出鼠标单击与鼠标单击事件,运行结果如下:

---------------------------------------------------------------------------------------------------------------------------------

大家有问题可以与我交流~

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值