Qt 系统相关 - 事件2
Qt 事件
定时器
Qt 中在进行窗口程序的处理过程中,经常要周期性的执行某些操作,或者制作一些动画效果,使用定时器就可以实现。所谓定时器就是在间隔一定时间后,去执行某一个任务。定时器在很多场景下都会使用到,如弹窗自动关闭之类的功能等。
Qt中的定时器分为 QTimerEvent 和 QTimer 这两个类。
QTimerEvent 类 用来描述一个定时器事件。在使用时需要通过
startTimer()
函数来开启一个定时器,这个函数需要输入一个以毫秒为单位的整数作为参数来表明设定的时间,它返回的整型值代表这个定时器。当定时器溢出时(即定时时间到达)就可以在timerEvent()
函数中获取该定时器的编号来进行相关操作。QTimer 类 来实现一个定时器,它提供了更高层次的编程接口,如:可以使用信号和槽,还可以设置只运行一次的定时器。
QTimerEvent 类
示例1:在UI界面上放置两个 Label 控件,一个让其1秒数字累加一次,一个让其2秒数字累加一次。
1. 新建项目,在UI界面文件放置两个 Label 控件;
2. 在 "widget.h" 头⽂件中声明 timerEvent() 函数,并定义两个整型变量;
3. 在 "widget.cpp" ⽂件中重写 timerEvent() 函数;
实现效果如下:
QTimer 类
示例:在UI界面放置一个 Label 标签,两个按钮,分别是 "开始" 和 "停止",当点击 "开始" 按钮时,开始每隔1秒计数一次,点击 "停止" 按钮时,暂停计数。
1. 设计 UI 界面如下:
2. 在 "widget.cpp" ⽂件中实现对应功能;
实现效果如下:
获取系统日期及时间
在 Qt 中,获取系统的日期及实时时间可以通过 QTimer 类和 QDateTime 类。
QDateTime 类提供了字符串格式的时间。字符串形式的时间输出格式由 toString()
方法中的 format 参数列表决定,可用的参数列表如下:
⽰例:获取系统⽇期及实时时间;
1. 设计UI界⾯⽂件;放置⼀个 Label控件,⽤来显⽰⽇期及时间,放置两个按钮:"开始" 和 "停⽌" ;
2. 在 "widget.h" 头⽂件中声明更新时间的槽函数;
3. 在 "widget.cpp" ⽂件中实现对应功能;
实现效果如下:
窗口移动和大小改变事件
在Qt框架中,窗口的移动和大小改变是通过一系列的事件来处理的。以下是一些与窗口移动和大小改变相关的主要事件:
resizeEvent(QResizeEvent *event)
: 当窗口或窗口内的部件大小发生变化时,会触发此事件。你可以重写这个事件处理函数来执行一些自定义的操作,比如调整内部布局或部件的大小。moveEvent(QMoveEvent *event)
: 当窗口位置发生变化时,会触发此事件。你可以在这个事件中获取窗口的新位置。showEvent(QShowEvent *event)
: 当窗口被显示时,会触发此事件。这可以用于初始化窗口的状态,或者在窗口首次显示时执行一些操作。hideEvent(QHideEvent *event)
: 当窗口被隐藏时,会触发此事件。这可以用于保存窗口的状态,或者在窗口被隐藏前执行一些清理工作。closeEvent(QCloseEvent *event)
: 当窗口尝试关闭时,会触发此事件。你可以在这个事件中执行一些清理工作,或者询问用户是否真的想要关闭窗口。paintEvent(QPaintEvent *event)
: 当窗口需要重绘时,会触发此事件。这通常发生在窗口大小改变、窗口被遮挡后重新显示或者调用了update()
函数之后。
在Qt中,可以通过继承QWidget
(或者任何其他窗口部件类)并重写上述事件处理函数来响应窗口的移动和大小改变事件。
事件分发器
概述
在 Qt 中,事件分发器(Event Dispatcher)是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从一个对象传递到另一个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e)
函数,来实现相关事件的捕获和拦截。
事件分发器工作原理
在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event()
函数。所有的事件都会进入到这个函数里面,那么我们处理事件就要重写这个 event()
函数。event()
函数本身不会去处理事件,而是根据 事件类型(type值) 调用不同的事件处理函数。事件分发器就是工作在应用程序向下分发事件的过程中,如下图:
如上图,事件分发器用于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e)
函数来实现。其返回值为布尔类型,若为 true,代表拦截,不向下分发。
Qt 中的事件是封装在 QEvent 类中,在 Qt 助手中输入 QEvent 可以查看其所包括的事件类型,如下图所示:
⽰例:
1. 在 "widget.h" 头⽂件中声明 ⿏标点击事件 和 事件分发器;如下图⽰:
2. 在 "widget.cpp" ⽂件中实现 ⿏标点击事件 和 拦截事件;
执行效果如下:
事件过滤器
在 Qt 中,一个对象可能经常要查看或拦截另外一个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。通过上面的学习,我们已经知道,Qt 创建了 QEvent 事件对象之后,会调用 QObject 的 event()
函数处理事件的分发。显然,我们可以在 event()
函数中实现拦截的操作。由于 event()
函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个 event()
函数。这当然相当麻烦,更不用说重写 event()
函数还得小心一堆问题。好在 Qt 提供了另外一种机制来达到这一目的:事件过滤器。
事件过滤器是在应用程序分发到 event事件分发器 之前,再做一次更高级的拦截。如下图所示:
事件过滤器的一般使用步骤:
安装事件过滤器;
重写事件过滤器函数:
eventFilter()
。
示例:
1. 新建 Qt 项目,基类选择 QWidget,同时勾选 UI 界面文件,如下图所示;
2. 设计 UI 文件,如下所示:
3. 在项目中新增一个类 --- MyLabel
先选中项⽬名称 QEvent,点击⿏标右键,选择 add new ... ,弹出如下对话框:
4. 选择:Choose .... ,弹出如下界⾯:
5. 此时项⽬中会新添加以下两个⽂件:
6. 在 UI ⽂件中选中 Label,右键 ------> 提升为...
7. 当点击 "提升为... " 之后,弹出如下对话框:
8. 在 "mylabel.h" 中声明 ⿏标点击事件 和 事件分发器;
9. 在 "mylabel.cpp" ⽂件中实现⿏标点击事件和事件分发器;
10. 在 "widget.h" 头⽂件中声明事件过滤器函数;
11. 在 "widget.cpp" ⽂件中实现事件过滤器的两个步骤;
执行效果如下: