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);
}
相关推荐
Komorebi.py5 分钟前
【Linux】-学习笔记05
linux·笔记·学习
----云烟----6 小时前
QT中QString类的各种使用
开发语言·qt
朝九晚五ฺ8 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
猫爪笔记9 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
pq113_610 小时前
ftdi_sio应用学习笔记 3 - GPIO
笔记·学习·ftdi_sio
澄澈i10 小时前
设计模式学习[8]---原型模式
学习·设计模式·原型模式
爱米的前端小笔记11 小时前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘
alikami11 小时前
【前端】前端学习
学习
一只小菜鸡..11 小时前
241118学习日志——[CSDIY] [ByteDance] 后端训练营 [06]
学习
「QT(C++)开发工程师」12 小时前
【qt版本概述】
开发语言·qt