欢迎光临
我们一直在努力

【Qt】系统相关(下)

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

9efbcbc3d25747719da38c01b3fa9b4f.gif

目录

 Qt 多线程

Qt 多线程概述

QThread 常用 API

使用线程

线程安全

互斥锁

条件变量

信号量

Qt⽹络

UDPSocket

核⼼API概览

回显服务器

回显客⼾端

TCPSocket

核⼼API概览

回显服务器

回显客⼾端

HTTPClient

核⼼API

代码⽰例

Qt⾳视频

Qt⾳频

核⼼API概览

⽰例

Qt视频

核⼼API概览


前言

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

             今日更新了Qt系统相关的内容     🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

 Qt 多线程

Qt 多线程概述

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

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

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

QThread 常用 API

使用线程

创建线程的步骤:

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

    首先新建 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概览

    赞(0)
    未经允许不得转载:171主机测评 » 【Qt】系统相关(下)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址