Qt事件
事件介绍
事件是应⽤程序内部或者外部产⽣的事情或者动作的统称。在 Qt 中使⽤⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当⽤⼾按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件。⼀些事件是在⽤⼾操作时发出,如键盘事件、⿏标事件等,另⼀些事件则是由系统本⾝⾃动发出,如定时器事件。常⻅的 Qt 事件如下
信号槽就是对事件的封装,事件是信号槽的底层机制。

信号槽中是通过connect来关联信号和槽函数的,在事件这里,需要让当前的类重写某个事件处理函数,这里用到的是多态的机制,创建子类,让其继承自Qt的类,然后在子类中重写虚函数,后续事件触发的过程中,就会通过多态这样的机制,执行到我们自己重写的虚函数。
事件的处理
事件处理⼀般常⽤的⽅法为:重写相关的 Event 函数。
在 Qt 中,⼏乎所有的 Event 函数都是虚函数,所以可以重新实现。如:在实现⿏标的进⼊和离开事件时,直接重新实现 enterEvent() 和 leaveEvent() 即可。
创建项目时,这里的演示基类选择QWidget

1.接着,在ui界面中,我们可以先创建一个QLabel
2.然后

给它设置一个边框,这样可以方便的观察进出
3.然后创建一个新的类,让它继承自QLabel

创建好后,项目中就会多出两个新的文件

4.用帮助文档进行查询,在重写虚函数这里,要经常使用到帮助文档

复制好后,粘贴到mylabel的头文件中
5.重写该虚函数

6.将之前创建的QLabel进行类型提升


这里输入我们之前自定义的类型,然后点击添加
然后再点击提升

7.再修改MyLabel的基类


8.运行程序

结果符合预期。
当鼠标进入时,label随机移动
我们还可以设计一下,使我们的鼠标刚进入label就让这个label在窗口内随机移动

因为MyLabel在ui这个对象中·,ui这个对象指针又在Widget中,因此我这里给MyLabel设置了两个公有成员变量,来记录Widget的窗口大小。

然后,在Widget的构造函数中对其进行了赋值


当⿏标点击时,获取对应的坐标值
在上述⽰例的基础上,在 mylabel.h 中声明 mousePressEvent() ⽅法;
依旧还是先在文档中进行查询

重写虚函数
为了防止干扰,先把之前的飞雷神功能注释掉

对于某些事件,比如鼠标移动事件,Qt程序为了保证流畅性,默认情况下不会对鼠标移动进行追踪,也就是鼠标移动时不会调用 mouseMoveEvent,除非显示告诉Qt需要开启追踪。
鼠标滚轮事件
重写虚函数


鼠标双击事件
⿏标双击事件是通过虚函数:mouseDoubleClickEvent() 来实现的。


鼠标释放事件
⿏标释放事件是通过虚函数 mouseReleaseEvent() 来捕获的。


定时器
Qt中的定时器分为 QTimerEvent 和 QTimer 这2个类。
QTimerEvent类 ⽤来描述⼀个定时器事件。在使⽤时需要通过 startTimer() 函数来开启⼀个定时
器,这个函数需要输⼊⼀个以毫秒为单位的整数作为参数来表明设定的时间,它返回的整型值代表
这个定时器。当定时器溢出时(即定时时间到达)就可以在 timerEvent() 函数中获取该定时器的
编号来进⾏相关操作。
•
QTimer类 来实现⼀个定时器,它提供了更⾼层次的编程接⼝,如:可以使⽤信号和槽,还可以设
置只运⾏⼀次的定时器。
QTimer的背后就是QTimerEvent定时器事件支撑的。

使用 QTimerEvent实现定时器
在 "widget.h" 头⽂件中声明 timerEvent() 函数
先通过 startTimer来启动一个定时器,并返回一个timer_id。这个id可以类似于Linux中的文件描述符,起到一个标识身份的效果。
先声明一个变量用来保存定时器的id,然后在构造函数中启动定时器

重写虚函数


使用 QTimer类实现定时器
在Widget中添加一个QTimer对象指针,然后在构造函数中初始化 ,并关联槽函数

槽函数的实现:


Qt文件
我们之前也学过了一些关于文件的操作:

在 Qt 中,⽂件读写的类为 QFile 。QFile 的⽗类为 QFileDevice ,QFileDevice 提供了⽂件交互操作的层功能。 QFileDevice 的⽗类是 QIODevice,QIODevice 的⽗类为 QObject 。

关于上述的类:
QFile 是⽤于⽂件操作和⽂件数据读写的类,使⽤ QFile 可以读写任意格式的⽂件。
•
QSaveFile 是⽤于安全保存⽂件的类。使⽤ QSaveFile 保存⽂件时,它会先把数据写⼊⼀个临时⽂
件,成功提交后才将数据写⼊最终的⽂件。如果保存过程中出现错误,临时⽂件⾥的数据不会被写
⼊最终⽂件,这样就能确保最终⽂件中不会丢失数据或被写⼊部分数据。 在保存⽐较⼤的⽂件或复
杂格式的⽂件时可以使⽤这个类,例如从⽹络上下载⽂件等。
•
QTemporaryFile 是⽤于创建临时⽂件的类。使⽤函数 QTemporaryFile::open() 就能创建⼀个⽂件
名唯⼀的临时⽂件,在 QTemporaryFile 对象被删除时,临时⽂件被⾃动删除。
•
QTcpSocket 和 QUdpSocket 是分别实现了 TCP 和 UDP 的类。
•
QSerialPort 是实现了串⼝通信的类,通过这个类可以实现计算机与串⼝设备的通信。
•
QBluetoothSocket 是⽤于蓝⽛通信的类。⼿机和平板计算机等移动设备有蓝⽛通信模块,笔记本
电脑⼀般也有蓝⽛通信模块。通过QBluetoothSocket类,就可以编写蓝⽛通信程。如编程实现笔
记本电脑与⼿机的蓝⽛通信。
•
QProcess 类⽤于启动外部程序,并且可以给程序传递参数。
•
QBuffer 以⼀个 QByteArray 对象作为数据缓冲区,将 QByteArray 对象当作⼀个 I/O 设备来读写。
关于QFile类
读数据:QFile 类中提供了多个⽅法⽤于读取⽂件内容;如 read()、readAll()、readLine()等。
•
写数据:QFile 类中提供了多个⽅法⽤于往⽂件中写内容;如 write()、writeData()等。
•
关闭⽂件:⽂件使⽤结束后必须⽤函数 close() 关闭⽂件。

访问⼀个设备之前,需要使⽤ open()函数 打开该设备,⽽且必须指定正确的打开模式,QIODevice 中所有的打开模式由 QIODevice::OpenMode 枚举变量定义
QIODEvice继承自QIODeviceBase,在QIODeviceBase中有一个enum:


读取⽂件内容
这里用了一个垂直布局管理器
点击按钮就会打开一个文件对话框

代码:

打开的效果:
这里的read接口
它的返回值其实是一个QByteArray,但是它可以直接转化成一个QString,所以我们直接用QString接收了。
关于文件打开后,不用了一定要记得关闭。因为文件描述符表存在上限,如果对打开的文件一直不关闭,那么就会使文件描述符表被占满,后续就不能打开文件了。
另外,我们这里打开的是一个文本,用QString接收内容没关系,但如果是二进制文件,此时交给QString就不合适了。
追加写文件
代码:
结果:
确实写上去了,只是没有换行。
⽂件和⽬录信息类
QFileInfo 是 Qt 提供的⼀个⽤于获取⽂件和⽬录信息的类,如获取⽂件名、⽂件⼤⼩、⽂件修改⽇期等。QFileInfo类中提供了很多的⽅法,常⽤的有:
isDir() 检查该⽂件是否是⽬录;
•
isExecutable() 检查该⽂件是否是可执⾏⽂件;
•
fileName() 获得⽂件名;
•
completeBaseName() 获取完整的⽂件名;
•
suffix() 获取⽂件后缀名;
•
completeSuffix() 获取完整的⽂件后缀;
•
size() 获取⽂件⼤⼩;
•
isFile() 判断是否为⽂件;
•
fileTime() 获取⽂件创建时间、修改时间、最近访问时间等
获取文件信息
