Qt 自定义QWidget中区分鼠标单击和双击

定义了一个控件,继承自QWidget,但是在使用鼠标单击和双击事件的时候,出现了问题:

#pragma once

#include <QWidget>
#include "ui_UserButton.h"

//用户自定义按钮

class UserButton : public QWidget {
	Q_OBJECT

public:
	UserButton(QWidget *parent = Q_NULLPTR);
	~UserButton();

private:
	QSize sizeHint()const override;
	QSize minimumSizeHint() const override;

	void paintEvent(QPaintEvent *)override;

	void mousePressEvent(QMouseEvent *)override;//响应鼠标单击事件
	void mouseDoubleClickEvent(QMouseEvent*)override;//响应鼠标双击事件
private:
	Ui::UserButton ui;
};

#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include "UserButton.h"

UserButton::UserButton(QWidget *parent)
	: QWidget(parent) {
}

UserButton::~UserButton() {
}

QSize UserButton::sizeHint() const {
	return QSize(120, 30);
}

QSize UserButton::minimumSizeHint() const {
	return QSize(120, 30);
}

void UserButton::paintEvent(QPaintEvent *) {
	//绘制准备工作,启用反锯齿
	QPainter painter(this);
	painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

	painter.save();
	painter.setPen(Qt::NoPen);
	painter.setBrush(Qt::darkGray);
	painter.drawRoundedRect(0, 0, width(), height(), 5.0, 5.0);
	painter.restore();
}

void UserButton::mousePressEvent(QMouseEvent *e) {
	if (e->button() & Qt::LeftButton) {
		qDebug() << "mousePressEvent";
	}
}

void UserButton::mouseDoubleClickEvent(QMouseEvent*e) {
	if (e->button() & Qt::LeftButton) {
		qDebug() << "mouseDoubleClickEvent";
	}
}

单击控件的时候,输出:

mousePressEvent

单击鼠标左键的时候,程序还是可以正确的响应的。
但是双击控件的时候输出:

mousePressEvent
mouseDoubleClickEvent

这就说明双击鼠标左键的时候,首先响应了鼠标左键的单击事件,然后再相应双击事件,但是我们希望鼠标左键双击的时候不要相应单击事件,而是直接相应双击事件即可。

解决办法:
可以定义一个定时器,单击鼠标左键的时候,第一次启动定时器,在300毫秒内,没有第二次单次鼠标左键,我们就认为是这是一个单击事件,否则就是双击事件。
修改之后的代码如下:

#pragma once

#include <QWidget>
#include "ui_UserButton.h"

//用户自定义按钮

class QTimer;

class UserButton : public QWidget {
	Q_OBJECT

public:
	UserButton(QWidget *parent = Q_NULLPTR);
	~UserButton();

private:
	QSize sizeHint()const override;
	QSize minimumSizeHint() const override;

	void paintEvent(QPaintEvent *)override;

	void mousePressEvent(QMouseEvent *)override;
#if 0
	//这部分代码不在需要
	void mouseDoubleClickEvent(QMouseEvent*)override;
#endif
private:
	Ui::UserButton ui;

private slots:
	void slotClickTime();

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

#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QTimer>
#include "UserButton.h"

UserButton::UserButton(QWidget *parent)
	: QWidget(parent) {

	_clickTimer = new QTimer;
	connect(_clickTimer, SIGNAL(timeout()), this, SLOT(slotClickTime()));
}

UserButton::~UserButton() {
}

QSize UserButton::sizeHint() const {
	return QSize(120, 30);
}

QSize UserButton::minimumSizeHint() const {
	return QSize(120, 30);
}

void UserButton::paintEvent(QPaintEvent *) {
	//绘制准备工作,启用反锯齿
	QPainter painter(this);
	painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

	painter.save();
	painter.setPen(Qt::NoPen);
	painter.setBrush(Qt::darkGray);
	painter.drawRoundedRect(0, 0, width(), height(), 5.0, 5.0);
	painter.restore();
}

void UserButton::mousePressEvent(QMouseEvent *e) {
	if (e->button() & Qt::LeftButton) {
		if (!_clickTimer->isActive()) {
			_clickTimer->start(300);
			_clickCount++;
		} else {
			_clickCount++;
		}
	}
}

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

#if 0
//鼠标双击事件代码不在需要
void UserButton::mouseDoubleClickEvent(QMouseEvent*e) {
	if (e->button() & Qt::LeftButton) {
		qDebug() << "mouseDoubleClickEvent";
	}
}
#endif

鼠标单击按钮,输出:

"鼠标左键点击了一次"

鼠标双击按钮,输出:

"鼠标左键点击了两次"

这样就达到了,我们的要求!

aaa


版权声明:本文为wb175208原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。