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);
}
相关推荐
A懿轩A43 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
南宫生9 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__9 小时前
Web APIs学习 (操作DOM BOM)
学习
mahuifa9 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai
冷眼看人间恩怨9 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
数据的世界0111 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐11 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
OopspoO13 小时前
qcow2镜像大小压缩
学习·性能优化
A懿轩A14 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
云空14 小时前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv