QT学习之标签+鼠标/定时器

标签+鼠标

QEvent

需求鼠标进入控件范围会进行相关操作

在QEnterEvent类中

cpp 复制代码
[virtual protected] void QWidget::enterEvent(QEnterEvent *event)

虚成员函数可以进行重写

实现鼠标进入或离开Lable会打印输出

新建一个父类为QWidget的名字为mylable的C++类文件

先声明在.h文件这

cpp 复制代码
//鼠标进入事件
    void enterEvent(QEnterEvent *event);
    //鼠标离开事件
    void leaveEvent(QEvent *event);

在.cpp文件中实现为

cpp 复制代码
//鼠标进入事件
void myLable::enterEvent(QEnterEvent *event)
{
    qDebug()<<"鼠标进入";
}

//鼠标离开事件
void myLable::leaveEvent(QEvent *event)
{
    qDebug()<<"鼠标离开";
}

然后在ui界面拉一个Lable,右键提升为,可以看到标签的基类为QLable,而我们之前创建是基类为QWidget,所以要改为一样的QLable,

三个地方:

头文件

cpp 复制代码
#include <QLabel>

.h文件中

cpp 复制代码
class myLable : public QLabel
{
    Q_OBJECT
public:
    explicit myLable(QWidget *parent = nullptr);

    //鼠标进入事件
    void enterEvent(QEnterEvent *event);
    //鼠标离开事件
    void leaveEvent(QEvent *event);

signals:
};

.cpp文件中

cpp 复制代码
myLable::myLable(QWidget *parent)
    : QLabel{parent}
{}

再提升为,把类明myLable粘贴过来,添加,提升为,就可以实现相关打印输出功能了

鼠标事件的重新实现

在QLabel中有Reimplemented Protected Functions有重新实现的保护函数

和鼠标事件相关的有

cpp 复制代码
 virtual void mouseMoveEvent(QMouseEvent *ev) override
 virtual void mousePressEvent(QMouseEvent *ev) override
 virtual void mouseReleaseEvent(QMouseEvent *ev) override

先在.h文件中进行声明

cpp 复制代码
//重写
    virtual void mouseMoveEvent(QMouseEvent *ev);//virtual关键字可加可不加
    virtual void mousePressEvent(QMouseEvent *ev);
    virtual void mouseReleaseEvent(QMouseEvent *ev);

再在.cpp文件中进行重写

cpp 复制代码
//鼠标按下,想要获取按下的位置或者其他信息,在QMouseEvent *ev里面
 void myLable::mousePressEvent(QMouseEvent *ev)
{
     //判断鼠标左键按下
    if(ev->button() == Qt::LeftButton)
     {
    qDebug()<<"鼠标左键按下";
    //qt中的格式化  arg参数,链式编程,如果是想知道基于屏幕的坐标则为global
    QString str = QString("鼠标按下了  x= %1   y= %2    global x = %3    global y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
    qDebug()<<str;
    }
    else if(ev->button()==Qt::RightButton)
    {
       qDebug()<<"鼠标右键键按下";
    }
}

//鼠标释放
 void myLable::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标释放";
}

//鼠标移动
 void myLable::mouseMoveEvent(QMouseEvent *ev)
{
     //鼠标移动是一个连续的过程,因此不能直接==判断, 要用buttons来进行判断
    if(ev->buttons() & Qt::LeftButton)
     {
         qDebug()<<"鼠标左键移动";
    }
}

此时鼠标只有按下才会触发移动函数

可以在构造函数中加一句鼠标追踪函数

cpp 复制代码
myLable::myLable(QWidget *parent)
    : QLabel{parent}
{
    setMouseTracking(true);//设置鼠标追踪
}
cpp 复制代码
//鼠标移动
 void myLable::mouseMoveEvent(QMouseEvent *ev)
{
     //鼠标移动是一个连续的过程,因此不能直接==判断, 要用buttons来进行判断
    if(ev->buttons() & Qt::LeftButton)
     {
         qDebug()<<"鼠标左键移动";
    }
    qDebug()<<"鼠标追踪移动";
}

标签+定时器

利用事件timerEvent

在Widget中重写

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //在构造函数中启动定时器
    startTimer(1000);//参数1 时间间隔 单位ms
}

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

//定时器
void Widget::timerEvent(QTimerEvent *e)
{
    static int num = 1;//变成全局变量
    ui->label_2->setText(QString ::number(num++));//int转QString
}

若是想再添加一个Label,以2秒的时间间隔进行定时

定时器开始函数返回值是int类型,是定时器的唯一id号,

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //在构造函数中启动定时器
    this->id1 = startTimer(1000);//参数1 时间间隔 单位ms
    this->id2 = startTimer(2000);//以2秒时间间隔运行
}

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

//定时器
void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == id1)
    {
        static int num1 = 1;//变成全局变量
        ui->label_2->setText(QString ::number(num1++));//int转QString
    }
    if(e->timerId() == id2)
    {
        static int num2 = 1;//变成全局变量
        ui->label_3->setText(QString ::number(num2++));//int转QString
    }
}

利用类QTimer

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //通过事件来操作定时器
    //在构造函数中启动定时器
    this->id1 = startTimer(1000);//参数1 时间间隔 单位ms
    this->id2 = startTimer(2000);//以2秒时间间隔运行

    //定时器的第二种方式
    QTimer *timer = new QTimer(this);
    timer->start(500);//0.5秒发出信号

    connect(timer,&QTimer::timeout,this,[=](){
        static int num3 = 1;//变成全局变量
        ui->label_4->setText(QString ::number(num3++));
    });
    //也可以实现按下按钮定时器停止,利用    timer->stop();
}

事件分发器

在系统接收到信号时会通过一个事件分发器来管理事件,boo; event(QEvent * ev),返回值是bool类型,为true时说明用户要自己处理这个事件,不向下分发事件,进行事件的拦截。

可以针对鼠标事件进行事件的拦截操作案例

cpp 复制代码
//拦截鼠标按下
bool myLable::event(QEvent *e)
{
    if(e->type() == QEvent::MouseButtonPress)
    {
        qDebug()<<"阻拦后鼠标按下";
        return true;//true代表用户自己处理这个事件,不向下分发
    }

    //其他事件交给父类处理,默认myLabel的父类是QLabel
    return QLabel::event(e);
}

事件过滤器

可以在程序分发到event事件之前再做一次高级拦截

使用有两个步骤:

1、给控件安装事件过滤器'

在构造函数中安装

cpp 复制代码
//给对应的事件安装事件过滤器,在此案例中叫label
    ui->label->installEventFilter(this);//通过这个Widget来安装

2、重写eventfilter()

cpp 复制代码
//重写eventFilter事件,第一个参数:控件,第二个参数:事件
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->label )
    {
        if(event->type() == QEvent::MouseButtonPress)
        {
            qDebug()<<"高级拦截按下";
            return true;
        }
    }

    //其他默认处理
    return QWidget::eventFilter(watched,event);
}
相关推荐
PerfumerKarma18 分钟前
【WebGPU学习杂记】数学基础拾遗(2)变换矩阵中的齐次坐标推导与几何理解
学习·线性代数·矩阵
knight_202429 分钟前
嵌入式学习日志————对射式红外传感器计次
stm32·单片机·嵌入式硬件·学习
go54631584651 小时前
基于分组规则的Excel数据分组优化系统设计与实现
人工智能·学习·生成对抗网络·数学建模·语音识别
●VON1 小时前
重生之我在暑假学习微服务第二天《MybatisPlus-下篇》
java·学习·微服务·架构·mybatis-plus
枫叶丹41 小时前
【Qt开发】信号与槽(二)-> 信号和槽的使用
开发语言·qt
Yu_Lijing1 小时前
MySQL进阶学习与初阶复习第四天
数据库·学习·mysql
好学且牛逼的马3 小时前
学习随笔录
学习
我爱学嵌入式4 小时前
C语言第 9 天学习笔记:数组(二维数组与字符数组)
c语言·笔记·学习
im_AMBER7 小时前
学习日志19 python
python·学习
励志要当大牛的小白菜8 小时前
ART配对软件使用
开发语言·c++·qt·算法