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);
}
相关推荐
Easocen29 分钟前
Mybatis学习笔记(五)
笔记·学习·mybatis
丑小鸭是白天鹅2 小时前
嵌入式C语言学习笔记之枚举、联合体
c语言·笔记·学习
看到我,请让我去学习3 小时前
Qt— 布局综合项目(Splitter,Stacked,Dock)
开发语言·qt
创想未来CTF3 小时前
Qt同步处理业务并禁用按钮
qt
楼田莉子3 小时前
C++算法题目分享:二叉搜索树相关的习题
数据结构·c++·学习·算法·leetcode·面试
奶黄小甜包5 小时前
C语言零基础第18讲:自定义类型—结构体
c语言·数据结构·笔记·学习
rannn_1117 小时前
【MySQL学习|黑马笔记|Day7】触发器和锁(全局锁、表级锁、行级锁、)
笔记·后端·学习·mysql
喜欢吃燃面8 小时前
C++算法竞赛:位运算
开发语言·c++·学习·算法
传奇开心果编程8 小时前
【传奇开心果系列】Flet框架实现的家庭记账本示例自定义模板
python·学习·ui·前端框架·自动化
谱写秋天8 小时前
Qt 5.5 的安装与配置(使用 VSCode编辑)
开发语言·vscode·qt