当前位置: 首页 > news >正文

[Qt][Qt 事件][下]详细讲解

目录

  • 1.定时器
    • 0.是什么?
    • 1.QTimerEvent
    • 2.QTimer
    • 3.获取系统⽇期及时间
  • 2.事件分发器
    • 1.概述
    • 2.事件分发器工作原理
    • 3.使用
  • 3.事件过滤器
    • 0.是什么?
    • 2.使用


1.定时器

0.是什么?

  • 在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定时器就可以实现
  • 定时器:就是在间隔⼀定时间后,去执⾏某⼀个任务
  • Qt中的定时器分为QTimerEventQTimer这2个类

1.QTimerEvent

  • QTimerEvent:⽤来描述⼀个定时器事件
  • 使用
    • startTimer():开启⼀个定时器
      • 参数:以毫秒为单位的整数作为参数来表明设定的时间
      • 返回值:一个整形的身份标识,代表这个定时器
    • 当定时器溢出时(即定时时间到达)就可以在timerEvent()中获取该定时器的编号来进⾏相关操作
    • killTimer:关闭定时器
  • 注意:如果一个程序中存在多个定时器(startTimer创建的定时器),此时每个定时器都会触发timerEvent()
  • 示例
    // 构造函数中
    {// 开启定时器事件.// 此处 timerId 是一个定时器的身份标识.timerId = this->startTimer(1000);
    }void Widget::timerEvent(QTimerEvent* event)
    {// 先判定一下这次触发是否是想要的定时器触发的.if (event->timerId() != this->timerId) {return;}int value = ui->lcdNumber->intValue();if (value <= 0) {// 停止定时器this->killTimer(this->timerId);return;}value -= 1;ui->lcdNumber->display(value);
    }
    

2.QTimer

  • QTimer底层是QTimerEvent
  • QTimer实现⼀个定时器,它提供了更⾼层次的编程接⼝
    • 如:可以使⽤信号和槽,还可以设置只运⾏⼀次的定时器
  • 示例
    QTimer* timer = new QTimer(this);connect(ui->btn1, &QPushButton::clicked, [=](){timer->start(1000);
    });connect(timer, &QTimer::timeout, [=](){static int num = 1;ui->label->setText(QString::number(num++));
    });connect(ui->btn2, &QPushButton::clicked, [=](){timer->stop();
    });
    

3.获取系统⽇期及时间

  • 在Qt中,获取系统的⽇期及实时时间可以通过QTimer类和QDateTime

  • QDateTime类提供了字符串格式的时间,输出格式由toString()⽅法中的format参数列表决定

    请添加图片描述

  • 示例

    // 构造函数中
    {QTimer* timer = new QTimer(this);connect(ui->btn1, &QPushButton::clicked, [=](){timer->start(1000);});connect(ui->btn2, &QPushButton::clicked, [=](){timer->stop();});connect(timer, &QTimer::timeout, this, &Widget::TimeUpdate);
    }void Widget::TimeUpdate()
    {QString t = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");ui->label->setText(t);
    }
    

2.事件分发器

1.概述

  • 在Qt中,事件分发器(EventDispatcher)是⼀个核⼼概念,⽤于处理GUI应⽤程序中的事件
    • 属于Qt事件机制背后的一些逻辑
    • 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
  • 事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消
  • 每个继承⾃QObject类或QObject类本⾝都可以在本类中重写bool event(QEvent* e),来实现相关事件的捕获和拦截

2.事件分发器工作原理

  • 在Qt中,发送的事件都是传给了QObject对象,更具体点是传给了QObject对象的event()
    • 所有的事件都会进⼊到这个函数⾥⾯
      • 那么处理事件就要重写这个event()函数
    • event()函数本⾝不会去处理事件,⽽是根据事件类型(type)调⽤不同的事件处理函数
  • 事件分发器就是⼯作在应⽤程序向下分发事件的过程中
    • 事件分发器⽤于分发事件,在此过程中,事件分发器也可以做拦截操作
    • 事件分发器主要是通过bool event(QEvent* e)来实现
      • 返回值:若为ture,代表拦截,不向下分发
        请添加图片描述

3.使用

  • Qt中的事件是封装在QEvent类中,其所包括的事件类型:

    请添加图片描述

  • 示例:拦截鼠标左键单击事件

    void Widget::mousePressEvent(QMouseEvent* event)
    {if(event->button() == Qt::LeftButton){qDebug() << "鼠标左键被按下";}
    }bool Widget::event(QEvent* ev)
    {if(ev->type() == QEvent::MouseButtonPress){qDebug() << "Event中鼠标被按下";return true; // 返回true,代表拦截,不向下分发}// 其他事件交给父类处理(默认处理)return QWidget::event(ev);
    }
    

3.事件过滤器

0.是什么?

  • 在Qt中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件
    • 例如:对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等
    • 属于Qt事件机制背后的一些逻辑
    • 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
  • Qt创建了QEvent事件对象之后,会调⽤QObjectevent()函数处理事件的分发,可以在event()函数中实现拦截的操作
    • 由于event()protected的,因此,需要继承已有类
    • 如果组件很多,就需要重写很多个event()
      • 这当然相当⿇烦,更不⽤说重写event()还得⼩⼼⼀堆问题
      • 好在Qt提供了另外⼀种机制来达到这⼀⽬的:事件过滤器
  • 事件过滤器是在应⽤程序分发到event事件分发器之前,再做⼀次更⾼级的拦截
    请添加图片描述

2.使用

  • 事件过滤器的⼀般使⽤步骤
    • 安装事件过滤器
    • 重写事件过滤器函数:eventfilter()
  • 示例
    {void MyLabel::mousePressEvent(QMouseEvent* event){QString str = QString("鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();}void MyLabel::event(QEvent* ev){if(ev->type() == QEvent::MouseButtonPress){QMouseEvent* event = static_cast<QMouseEvent* e>(e);QString str = QString("event中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();return true; // 返回true,代表拦截,不向下分发}// 其他事件交给父类处理(默认处理)return QWidget::event(ev);}
    }
    ----------------------------------------------------------------------
    {// Widget构造函数中{// 步骤1:给label安装事件过滤器  this:当前窗口安装事件过滤器ui->label->installEventFilter(this);}// 步骤2:重写eventFilter事件bool Widget::eventFilter(QObject* obj, QEvent* e){if(obj == ui->label) // 判断控件{if(e->type == QEvent::MouseButtonPress){QMouseEvent* event = static_cast<QMouseEvent* e>(e);QString str = QString("事件过滤器中鼠标按下: x = %1, y = %2").arg(event->x()).arg(event->y());qDebug() << str.toUtf8().data();return true;}}// 其他事件交给父类处理return QWidget::event(ev);}
    }
    
http://www.lryc.cn/news/424827.html

相关文章:

  • 八股总结----计算机网络
  • Laravel 框架开发 ERP 系统,技术选型和分析以及实施计划
  • 【Vue3】嵌套路由
  • pygame小游戏
  • .Net Core IIS 程序报错 Access to the path c:\\windows\\TEMP\\poifiles is denied
  • 交换机VLAN配置中Tagged与Untagged端口的差异和应用区别
  • @OneToOne注解的作用
  • vue动画、过渡效果
  • 在 Vue 3 项目中使用 Element UI Plus <el-calendar>组件与时区处理
  • 【系统架构设计】计算机网络
  • 《中国数据库前世今生》——历史的深度与未来的展望
  • web前端之实现霓虹灯背景魔术卡、旋转的背景动画、模糊效果、边框、变量、filter
  • 几款免费的时序数据库对比
  • 基于springboot的乐享田园系统
  • 深入解析Objective-C中NSParagraphStyle的段落样式处理艺术
  • Qt编程技巧小知识点(2)GPIB缓存区数据读取
  • 数的个位相加
  • 专业技能(挖坑填坑)——MYSQL的索引、日志、事务、存储引擎、锁机制等相关原理
  • C++(27): 线程池
  • 每日一题-贪心算法
  • PSO 算法实例(手动推导过程)
  • 解决antd TreeSelect 返回值不包含父节点问题 -自定义组件(react)
  • 花四小时,写了个在线实时绘制等值面图小软件,明晚上线,喜欢的小伙伴关注哦
  • c++的vector用法
  • 【Linux网络】Linux网络初探:开启网络世界的大门
  • 目录、用户与组、出错相关函数、时间函数
  • <keep-alive> 一分钟了解
  • Android 启动动画太生硬
  • 深度学习中常用概念总结
  • 进 程