QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)

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)如何查找对应的函数
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第1张图片
这里面包含类的使用说明及相关函数,可以看到,鼠标离开的事件函数为leaveEvent()。
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第2张图片
可以看到这是一个QWidget类的函数,其属性为[virtual protected],代表这个函数时可以被覆盖重写的(此处可以参考C++中虚函数及多态进行理解)

[virtual protected] void QWidget::enterEvent(QEvent *event)

(2)实现功能:鼠标进入一个label就显示一段话
首先需要创建一个程序,创建程序的过程参考:如何在qcreate中创建一个程序
但在此处,我选择了系统自动生成UI文件
拖一个label进入UI中
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第3张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第4张图片
捕捉需要做一些自定义的框架
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第5张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第6张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第7张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第8张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第9张图片
(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"控件,右键选择“提升为”
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第10张图片
(3)选择基类为"QLabel",粘贴myLabel,选择“添加”
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第11张图片
(4)选择“提升”
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第12张图片
(5)可以看到"TextLabel"控件已提升为"QLabel"类,这个时候鼠标移进移出就可以捕捉到事件
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第13张图片
(6)但是这个TextLabel默认是没有边框,那么去找的时候就不容易找到,此处有一个技巧,给他设置边框
QFram–>FramShape–>Box
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第14张图片
(7)点击运行,鼠标进入或者离开方框就会打印出qDebug内容
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第15张图片
3. 如何实现利用鼠标事件打印出鼠标在窗口内的坐标点及在整个屏幕的坐标点呢?

Qt的assistant中查看QLabel可覆盖的虚函数(使用了virtual代表可以进行覆盖)
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第16张图片
在鼠标事件的类中查看获取坐标点的函数
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第17张图片
程序:
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());

运行结果:
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第18张图片
4. 那我要实现当鼠标左键按下,提示信息怎么做呢?
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第19张图片
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第20张图片
找到对应的枚举值
QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第21张图片
对应代码

    //当鼠标左键按下,提示信息
    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;
    }

}

QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第22张图片
你会发现鼠标按下和释放时均会显示坐标点,但是移动过程中是没有显示的,这是因为按下和释放都是瞬时动作,而移动是一个连续性的动作。
那怎么解决上面的问题呢?
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;
    }

QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接)_第23张图片
7. 那如何实现只要在label上移动就可以打印出信息呢?(前面是进入与移出时或者单击等才有反应)
设置鼠标追踪,只要鼠标移动就可以自动捕获到鼠标移动打印出内容

myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标追踪状态,默认是false
setMouseTracking(true);
}

8. 学习视频地址:鼠标事件

你可能感兴趣的:(#,QT从入门到实战x篇,qt)