1. 本篇介绍Qt中的鼠标事件:
(1) 鼠标进入事件 enterEvent
(2) 鼠标离开事件 leaveEvent
(3) 鼠标按下 mousePressEvent(QMouseEvent *ev)
(4) 鼠标释放 mouseReleaseEvent(QMouseEvent *ev)
(5) 鼠标移动 mouseMoveEvent(QMouseEvent *ev)
(6) ev->x() x坐标 ev->y() y坐标
(7) ev->button()可以判断所有键 Qt::LeftButton Qt::RightButton
(8) ev->buttons()判断组合按键 判断move时的左右键 结合&操作键
(9) 格式化字符串 QString(“%1 %2”).arg(111).arg(222)
(10)设置鼠标追踪状态 setMouseTracking(true)
2. 我们来看一个比较常用的鼠标进入的enterEvent函数
(1)如何查找对应的函数
这里面包含类的使用说明及相关函数,可以看到,鼠标离开的事件函数为leaveEvent()。
可以看到这是一个QWidget类的函数,其属性为[virtual protected],代表这个函数时可以被覆盖重写的(此处可以参考C++中虚函数及多态进行理解)
[virtual protected] void QWidget::enterEvent(QEvent *event)
(2)实现功能:鼠标进入一个label就显示一段话
首先需要创建一个程序,创建程序的过程参考:如何在qcreate中创建一个程序
但在此处,我选择了系统自动生成UI文件
拖一个label进入UI中
捕捉需要做一些自定义的框架
(3). 在myLabel中写捕捉的实现
注意将基类改为QLabel
mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include //此处从#include 改为QLabel
class myLabel : public QLabel //此处基类改为QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
//鼠标进入事件
void enterEvent(QEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *);
signals:
};
#endif // MYLABEL_H
mylabel.cpp
#include "mylabel.h"
#include
//myLabel::myLabel(QWidget *parent) : QWidget(parent)改为myLabel::myLabel(QWidget *parent) : QLabel(parent)
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
}
//鼠标进入事件
void myLabel::enterEvent(QEvent *event)
{
qDebug()<<"鼠标进入";
}
//鼠标离开事件
void myLabel::leaveEvent(QEvent *)
{
qDebug()<<"鼠标离开";
}
捕捉的实现写完了,但是控件label并没有与事件连接起来,这个时候怎么操作呢?
一句话总结就是:将控件提升为自定义类下对象,即从QLabel下的对象label提升为myLabel下的对象,这样就可以使用自定义类内成员。
(1)将类名“myLabel”复制
(2)UI中选中"TextLabel"控件,右键选择“提升为”
(3)选择基类为"QLabel",粘贴myLabel,选择“添加”
(4)选择“提升”
(5)可以看到"TextLabel"控件已提升为"QLabel"类,这个时候鼠标移进移出就可以捕捉到事件
(6)但是这个TextLabel默认是没有边框,那么去找的时候就不容易找到,此处有一个技巧,给他设置边框
QFram–>FramShape–>Box
(7)点击运行,鼠标进入或者离开方框就会打印出qDebug内容
3. 如何实现利用鼠标事件打印出鼠标在窗口内的坐标点及在整个屏幕的坐标点呢?
Qt的assistant中查看QLabel可覆盖的虚函数(使用了virtual代表可以进行覆盖)
在鼠标事件的类中查看获取坐标点的函数
程序:
mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
//鼠标进入事件
void enterEvent(QEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *);
//鼠标按下
virtual void mousePressEvent(QMouseEvent *ev);
//鼠标释放
virtual void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动
virtual void mouseMoveEvent(QMouseEvent *ev);
signals:
};
#endif // MYLABEL_H
mylabel.cpp
#include "mylabel.h"
#include
#include
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
}
//鼠标进入事件
void myLabel::enterEvent(QEvent *event)
{
qDebug()<<"鼠标进入";
}
//鼠标离开事件
void myLabel::leaveEvent(QEvent *)
{
qDebug()<<"鼠标离开";
}
//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
//鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
qDebug()<<"鼠标释放";
}
//鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
qDebug()<<"鼠标移动";
}
QMouseEvent *ev和QEvent *event均是作为所写函数的成员对象,可以调用对应的成员的函数;
x(),y()是QMouseEvent类下用于显示窗口内点的坐标;
globalX(),globalY()是QMouseEvent类下用于显示屏幕内点的坐标
Qt中格式化字符串、占位符
//用于string类型的输出
QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
运行结果:
4. 那我要实现当鼠标左键按下,提示信息怎么做呢?
找到对应的枚举值
对应代码
//当鼠标左键按下,提示信息
if(ev->button()==Qt::LeftButton)
{
QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
上面实现了在左键按下时显示坐标信息
5. 那如果三个函数都采用左键判断,会有什么结果呢?
//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
//当鼠标左键按下,提示信息
if(ev->button()==Qt::LeftButton)
{
QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
}
//鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
if(ev->button()==Qt::LeftButton)
{
QString str=QString("鼠标释放了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
}
//鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
if(ev->button()==Qt::LeftButton)
{
QString str=QString("鼠标移动了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
}
你会发现鼠标按下和释放时均会显示坐标点,但是移动过程中是没有显示的,这是因为按下和释放都是瞬时动作,而移动是一个连续性的动作。
那怎么解决上面的问题呢?
6. 采用buttons()的联合按键功能
Qt::MouseButtons buttons() const
//&为位与运算符,只有在所有状态下均为左键按下时为真
if(ev->buttons() & Qt::LeftButton)
{
QString str=QString("鼠标移动了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
7. 那如何实现只要在label上移动就可以打印出信息呢?(前面是进入与移出时或者单击等才有反应)
设置鼠标追踪,只要鼠标移动就可以自动捕获到鼠标移动打印出内容
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标追踪状态,默认是false
setMouseTracking(true);
}
8. 学习视频地址:鼠标事件