【Qt】系统相关(下)

🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343
🔥 系列专栏: https://blog.csdn.net/qinjh_/category_13030435.html

目录

[Qt 多线程](#Qt 多线程)

[Qt 多线程概述](#Qt 多线程概述)

[QThread 常用 API](#QThread 常用 API)

使用线程

线程安全

互斥锁

条件变量

信号量

Qt⽹络

UDPSocket

核⼼API概览

回显服务器

回显客⼾端

TCPSocket

核⼼API概览

回显服务器

回显客⼾端

HTTPClient

核⼼API

代码⽰例

Qt⾳视频

Qt⾳频

核⼼API概览

⽰例

Qt视频

核⼼API概览


前言

    💬 hello! 各位铁子们大家好哇。

今日更新了Qt系统相关的内容

    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

Qt 多线程

Qt 多线程概述

在 Qt 中,多线程的处理一般是通过 QThread类 来实现。

QThread 代表一个在应用程序中可以独立控制的线程,也可以和进程中的其他线程共享数据。

QThread 对象管理程序中的一个控制线程。

QThread 常用 API

使用线程

创建线程的步骤:

  1. 自定义一个类,继承于 QThread,并且只有一个线程处理函数(和主线程不是同一个线程),这个线 程处理函数主要就是重写父类中的 run() 函数。
  2. 线程处理函数里面写入需要执行的复杂数据处理;
  3. 启动线程不能直接调用 run() 函数,需要使用对象来调用 start() 函数实现线程启动;
  4. 线程处理函数执行结束后可以定义一个信号来告诉主线程;
  5. 最后关闭线程。

示例:

首先新建 Qt 项目,设计 UI界面如下:

新建一个类,继承于 QThread类;

程序如下:

运行结果:

从10开始倒计时,到0时停止
说明:

1、线程函数内部不允许操作 UI 图形界面,一般用数据处理;

2、connect() 函数第五个参数表示的为连接的方式,且只有在多线程的时候才意义。

connect() 函数第五个参数为 Qt::ConnectionType,用于指定信号和槽的连接类型。同时影响信号的 传递方式和槽函数的执行顺序。Qt::ConnectionType 提供了以下五种方式:

线程安全

实现线程互斥和同步常⽤的类有:

  • 互斥锁:QMutex、QMutexLocker
  • 条件变量:QWaitCondition
  • 信号量:QSemaphore
  • 读写锁:QReadLocker、QWriteLocker、QReadWriteLock

互斥锁

互斥锁是⼀种保护和防⽌多个线程同时访问同⼀对象实例的⽅法,在Qt中,互斥锁主要是通过 QMutex类来处理。

  • QMutex

特点:QMutex是Qt框架提供的互斥锁类,⽤于保护共享资源的访问,实现线程间的互斥操作。

⽤途:在多线程环境下,通过互斥锁来控制对共享数据的访问,确保线程安全。

  • QMutexLocker

特点:QMutexLocker是QMutex的辅助类,使⽤RAII(ResourceAcquisitionIsInitialization)⽅式 对互斥锁进⾏上锁和解锁操作。

⽤途:简化对互斥锁的上锁和解锁操作,避免忘记解锁导致的死锁等问题。

  • QReadWriteLocker、QReadLocker、QWriteLocker

特点:

QReadWriteLock 是读写锁类,⽤于控制读和写的并发访问。

QReadLocker⽤于读操作上锁,允许多个线程同时读取共享资源。

QWriteLocker ⽤于写操作上锁,只允许⼀个线程写⼊共享资源。

⽤途:在某些情况下,多个线程可以同时读取共享数据,但只有⼀个线程能够进⾏写操作。读写锁提 供了更⾼效的并发访问⽅式。

示例:

运行结果:

示例:

在上面例子的基础上修改代码,使⽤QMutexLocker锁,结果不变。

条件变量

在多线程编程中,假设除了等待操作系统正在执⾏的线程之外,某个线程还必须等待某些条件满⾜才 能执⾏,这时就会出现问题。这种情况下,线程会很⾃然地使⽤锁的机制来阻塞其他线程,因为这只 是线程的轮流使⽤,并且该线程等待某些特定条件,⼈们会认为需要等待条件的线程,在释放互斥锁 或读写锁之后进⼊了睡眠状态,这样其他线程就可以继续运⾏。当条件满⾜时,等待条件的线程将被 另⼀个线程唤醒。

在Qt中,专⻔提供了QWaitCondition类来解决像上述这样的问题。

特点:QWaitCondition是Qt框架提供的条件变量类,⽤于线程之间的消息通信和同步。

⽤途:在某个条件满⾜时等待或唤醒线程,⽤于线程的同步和协调。

信号量

有时在多线程编程中,需要确保多个线程可以相应的访问⼀个数量有限的相同资源。例如,运⾏程序 的设备可能是⾮常有限的内存,因此我们更希望需要⼤量内存的线程将这⼀事实考虑在内,并根据可 ⽤的内存数量进⾏相关操作,多线程编程中类似问题通常⽤信号量来处理。信号量类似于增强的互斥 锁,不仅能完成上锁和解锁操作,⽽且可以跟踪可⽤资源的数量。

特点:QSemaphore是Qt框架提供的计数信号量类,⽤于控制同时访问共享资源的线程数量。

⽤途:限制并发线程数量,⽤于解决⼀些资源有限的问题。

Qt⽹络

和多线程类似,Qt为了⽀持跨平台,对⽹络编程的API也进⾏了重新封装

在进⾏⽹络编程之前,需要在项⽬中的 .pro ⽂件中添加 network 模块.

添加之后要⼿动编译⼀下项⽬,使QtCreator能够加载对应模块的头⽂件.

UDPSocket

核⼼API概览

主要的类有两个. QUdpSocket 和 QNetworkDatagram

QUdpSocket 表⽰⼀个UDP的socket⽂件.

QNetworkDatagram 表⽰⼀个UDP数据报

回显服务器

先添加 network 模块

创建界⾯,包含⼀个 QListWidget ⽤来显⽰消息

创建 QUdpSocket 成员

修改widget.h

修改widget.cpp,完成socket后续的初始化

⼀般来说,要先连接信号槽,再绑定端⼝.

如果顺序反过来,可能会出现端⼝绑定好了之后,请求就过来了.此时还没来得及连接信号槽.那么这 个请求就有可能错过了

实现 processRequest ,完成处理请求的过程。实现process 函数

此时,服务器程序编写完毕. 但是直接运⾏还看不出效果.还需要搭配客⼾端来使⽤

回显客⼾端

创建界⾯.包含⼀个 QLineEdit,QPushButton,QListWidget

  • 先使⽤⽔平布局把 QLineEdit和QPushButton放好,并设置这两个控件的垂直⽅向的sizePolicy 为Expanding
  • 再使⽤垂直布局把 QListWidget 和上⾯的⽔平布局放好.
  • 设置垂直布局的 layoutStretch 为 5, 1 (当然这个尺⼨⽐例根据个⼈喜好微调

代码:

运行:

当多项目时,需要指定项目运行。

运行结果如上图

如果我们想启动多个客户端,可以在build文件夹中找到exe文件打开即可。

TCPSocket

核⼼API概览

核⼼类是两个: QTcpServer 和 QTcpSocket

QTcpServer ⽤于监听端⼝,和获取客⼾端连接.

QTcpSocket ⽤⼾客⼾端和服务器之间的数据交互.

QByteArray⽤于表⽰⼀个字节数组.可以很⽅便的和QString进⾏相互转换

例如:

  • 使⽤QString的构造函数即可把QByteArray转成QString.
  • 使⽤QString的 toUtf8 函数即可把QString转成QByteArray

回显服务器

创建界⾯.包含⼀个 QListWidget ,⽤于显⽰收到的数据.

代码:

此时,服务器程序编写完毕. 但是直接运⾏还看不出效果.还需要搭配客⼾端来使⽤.

回显客⼾端

创建界⾯.包含⼀个QLineEdit,QPushButton,QListWidget

代码:

先启动服务器,再启动客⼾端(可以启动多个),最终执⾏效果:

HTTPClient

进⾏Qt开发时,和服务器之间的通信很多时候也会⽤到HTTP协议.

  • 通过HTTP从服务器获取数据.
  • 通过HTTP向服务器提交数据

核⼼API

关键类主要是三个. QNetworkAccessManager , QNetworkRequest , QNetworkReply

QNetworkAccessManager 提供了HTTP的核⼼操作


QNetworkRequest 表⽰⼀个HTTP请求(不含body)

如果需要发送⼀个带有body的请求(⽐如post),会在 QNetworkAccessManager 的post⽅法 中通过单独的参数来传⼊body.


其中的 QNetworkRequest::KnownHeaders 是⼀个枚举类型,常⽤取值:


QNetworkReply 表⽰⼀个HTTP响应.这个类同时也是 QIODevice 的⼦类.

此外, QNetworkReply 还有⼀个重要的信号 finished 会在客⼾端收到完整的响应数据之后触发

代码⽰例

给服务器发送⼀个GET请求

创建界⾯,包含⼀个 QLineEdit,QPushButton,,QPlainTextEdit

此处建议使⽤ QPlainTextEdit ⽽不是 QTextEdit .主要因为 QTextEdit 要进⾏富 ⽂本解析,如果得到的HTTP响应体积很⼤,就会导致界⾯渲染缓慢甚⾄被卡住

代码:

执⾏程序,观察效果:

发送POST请求代码也是类似.使⽤ manager->post() 即可.

Qt⾳视频

Qt⾳频

在Qt中,⾳频主要是通过QSound类来实现。但是需要注意的是QSound类只⽀持播放wav格式的 ⾳频⽂件。也就是说如果想要添加⾳频效果,那么⾸先需要将⾮wav格式的⾳频⽂件转换为wav格 式。

通过帮助⼿册查看QSound类如下:

注意: 使⽤QSound类时,需要添加模块:multimedia

核⼼API概览

⽰例

运行后,点击播放即可播放音频

Qt视频

在Qt中,视频播放的功能主要是通过QMediaPlayer类和QVideoWidget类来实现。在使⽤这两个类 时要添加对应的模块multimedia和multimediawidgets

核⼼API概览

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript