文章目录
虽然 Qt 是跨平台的 C++ 开发框架,Qt的很多能力其实是操作系统提供的,只不过 Qt 封装了系统的 API。
程序是运行在操作系统上的,需要系统给我们支撑
- 事件
- 文件操作
- 多线程编程
- 网络编程
- 多媒体(音频,视频)
前言:
在现代软件开发中,用户界面的交互性是衡量软件质量的重要标准之一。Qt,作为一个功能强大的跨平台C++开发框架,提供了丰富的机制来处理用户界面的各种交互事件。本文旨在深入探讨Qt中的事件处理机制,包括鼠标、键盘、定时器以及窗口事件等,并通过具体的示例代码,展示如何在Qt应用程序中重写和处理这些事件。通过本文的学习,开发者将能够更加灵活和深入地定制用户界面的行为,提升应用程序的交互性和用户体验。
1. 事件的介绍
- 信号槽:
用户进行的各种操作,就可能会产生出信号。可以给某个信号指定槽函数,当信号触发时,就能够自动执行到对应的槽函数。 - 事件非常类似
用户的各种操作,也会产生事件。程序员同样可以给事件关联上处理函数(处理的逻辑),当事件触发的时候,就能够执行对应的代码。
事件本身是操作系统提供的机制,Qt 也同样把操作系统事件机制经行了封装,拿到了 Qt 中,但是由于事件对应的代码编写起来的代码编写起来不是很方便,Qt 对事件机制又进行了进一步的封装,就得到了信号槽。
所以,信号槽就是对于事件的进一步封装,事件是信号槽的底层机制。
实际 Qt 开发过程中,绝大部分和用户之间进行的操作都是通过“信号槽”来完成的。有些特殊情况下,信号槽不一定能搞定(某个用户的动作行为,Qt
没有提供对应的信号…)此时就需要通过重写事件处理函数的形式,来手动处理事件的响应逻辑。
开发事件机制给咱们,咱们就可以根据实际需要进行更深度的定制化的 DIY 操作了。
用户进行了很多操作,就会产生很多的事件(当然也会产生很多的信号)
QEvent
: 事件概念
子类:代表各种具体的事件。不同场景下,要关注的点是不一样的,这些事件的子类中就会包含一些对应不同的属性。
2. 事件的处理
事件的处理一般常用的方法为:重写相关的 Event 函数
在 Qt 中,几乎所有的 Event
函数都是虚函数,所以可以重新实现。如:在实现鼠标的进入和离开事件时,直接重新实现 enterEvent()
和 leaveEvent()
即可。
让一段代码和某个事件关联起来,当事件触发的时候,就能指定到这段代码,之前信号槽这里通过 connect
来完成上述关联的,对于事件来说还不太一样。
对于事件来收,让当前类重写某个事件处理函数(这里用到的是“多态”的机制创建子类,继承自 Qt 已有的类,在子类中重写父类的事件处理函数)
后续的事件触发过程中,就会通过多态这样的机制,执行到咱们自己写的子类的函数中。
2.1. 示例1: 重写鼠标进入和鼠标离开事件
处理一下鼠标进入和鼠标离开:enterEvent()
和 leaveEvent()
它们都是虚函数,虚函数才能被子类重写。
边框显示出来,方便观察当前鼠标是否进去离开:
这里需要创建 QLabel
的子类,重写 enterEvent
和 leaveEvent
// label.h
#include <QWidget>
#include <QLabel>
class Label : public QLabel
{
Q_OBJECT
public:
Label(QWidget* parent); // QWidget* parent 让 Label有父控件
};
// label.cpp
#include "label.h"
Label::Label(QWidget* parent) : QLabel(parent)
{
}
为创建的类,重写 enterEvent
和 leaveEvent
这两个函数
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
要想重写父类的函数,就需要保证你这边写的函数名字和函数的参数列表都完全一致(形参名无所谓),谨防单词拼写错误。 正常来说Qt Creator
应该要能够提示出来,但实际上没有,所以这里只能通过手动的方式从Qt文档把它复制过来了,以免拼写错误。
上述代码,虽然重写了这两函数,但是还是有点问题
当前界面上的这个 Label 其实是 QLable, 不是咱们自己写的 Label,必须确保界面上的这个 label 是一个咱们自己定义的 Label 类的实例,才会执行到。
一定要确保,类名和头文件名与自定义的是匹配的,一定不能有拼写错误!
通过“提升为”这样的方式,就可以把 Qt Designer 中拖上去的控件的类型转换成自定义的控件类型。
2.2. 示例2:当鼠标点击时,获取对应的坐标值;
mousePressEvent
这个函数,按下左键,右键,滚轮都能触发。
有的鼠标还带有前进后退侧键,也是可以触发。
但是还有的鼠标,有更多的按键,更多按键就不一定了
void Label::mousePressEvent(QMouseEvent *event)
{