Qt中文件IO及线程类的介绍和使用

1. QFileDialog 文件对话框(熟悉)

Qt预设的用于选择文件或目录的对话框窗口类,继承自QDialog。QFileDialog本身不具备IO功能。

调用窗口通过静态成员函数:

此函数可以展示一个用于读取/保存单文件的对话框窗口。

参数1:父对象

参数2:窗口标题

参数3:基于哪个目录,默认为项目的工作目录

参数4:文件类型过滤器

返回值:用户选择的文件路径,如果选择失败,返回空字符串

2. QFileInfo 文件信息类(熟悉)

QFileInfo类用于获取文件信息。

常用函数如下所示。

  • QFileInfo::QFileInfo(const QString & file)

构造函数,参数是文件路径,需要注意的是参数无论是内容,QFileInfo对象都可以创建。

  • QDateTime QFileInfo::created() const

返回文件的创建日期和时间

  • bool QFileInfo::exists() const

文件是否存在

  • bool QFileInfo::isReadable() const

是否可读

  • qint64 QFileInfo::size() const

文件大小,返回的单位是字节

3. QFile 文件读写类

QFile类是进行文件读写的类,QIODevice是Qt所有IO类的基类,因此QIODevice类规定了很多IO通用的基础接口。

QFile类的常用函数如下所示。

  • QFile::QFile(const QString & name)

构造函数,参数为读写文件的路径

  • bool QIODevice::open(OpenMode mode) [virtual]

打开文件读写的数据流,参数为打开的模式。

  • bool QIODevice::atEnd() const [virtual]

是否读到文件尾

  • QByteArray QIODevice::read(qint64 maxSize)

读取最大字节数的数据,参数是最大字节数,返回值是读取后的字节数组对象。

  • qint64 QIODevice::write(const QByteArray & byteArray)

写出数据到文件,参数为需要写出的数据,返回值是实际写出的数据量,如果返回-1表示写出错误。

  • void QIODevice::close() [virtual]

关闭数据流

  • qint64 QIODevice::size() const [virtual]

获取可读的字节数

4. UI与耗时操作

在默认的情况下,程序员编写Qt程序只在一个线程(主线程)中运行。但是有时候这个线程会出现一些耗时操作(例如文件IO、网络、复杂算法等),这些耗时操作会导致主线程阻塞,此时用户发起的一些常规UI操作就无法得到及时的响应,此时操作系统检测一些关闭等UI操作无法及时响应则会弹出程序未响应窗口。

Windows等桌面操作系统会引导用户选择关闭还是等待。

解决方案就是使用多线程,主线程只执行UI相关操作,子线程执行耗时操作

5. QThread 线程类(掌握)

5.1 复现未响应

QThread类是Qt的线程类,其中有一个静态成员函数:

  • void QThread::msleep(unsigned long msecs) [static]

使当前线程强制睡眠,参数为睡眠时间,单位毫秒。

5.2 创建并启动线程

创建并启动一个线程的步骤如下:

1. 在Qt Creator中选中项目名称后,鼠标右键,点击“添加新文件”。

2. 在弹出的窗口中,按照下图所示配置自定义线程类信息。

3. 在“项目管理”界面,直接点击“完成”。可以在项目中看到,线程类已经创建完成。

4. 在自定义线程类中,覆盖QThread类中的run函数。

void QThread::run() [virtual protected]

此函数是子线程的起始点,此函数执行完成后,子线程也执行结束。

5. 在run函数中编写子线程要执行的代码,此函数不能包含UI操作。

6. 在主线程中创建子线程类对象,并调用start函数启动子线程。

void QThread::start(Priority priority = InheritPriority) [slot]

参数为线程执行的优先级。

5.3 优先级

不同的线程对象可以拥有不同的优先级,优先级代表cpu的一种选择偏向,具体取决于cpu对线程的调度。

除了使用start函数在启动时直接设置优先级外,当线程运行时,也可以使用下面的函数设置优先级;如果线程没有运行,此函数无效。

  • void QThread::setPriority(Priority priority)

参数为不同的优先级。

5.4 线程停止

在实际的开发中尽量不要停止线程,本次提供两种停止的方式:

1. 调用terminate函数

void QThread::terminate() [slot]

强行停止线程执行

2. 给耗时操作循环体设置标志位,通过设置标志位的数值,停止循环,间接使run函数执行完毕,从而达到停止线程的效果。

        子线程执行了耗时操作(循环睡眠),主线程接收子线程操作的通知,在实际的开发中,主线程接收到子线程耗时操作的通知后可能会刷新UI显示(例如显示文件读写的进度),这种情况下需要使用信号槽进行两个线程之间的通信。

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt的多线程和串口调试助手(Serial Port Helper)是如何结合使用的呢? 在Qt,可以通过使用QObject::moveToThread()函数将一个对象移动到另一个线程执行。这对于串口调试助手来说非常有用,因为串口通信通常涉及到IO操作,而在主线程(通常是GUI线程执行IO操作会导致界面卡顿。 首先,我们创建一个继承自QObject的SerialPortHelper,用于处理串口通信。在该,我们实现了串口的打开、关闭、读取和写入等功能。为了将该移动到一个新的线程执行,我们需要创建一个新的QThread对象,并将SerialPortHelper对象移动到该线程。 在主窗口(或其他需要使用串口调试助手的地方),我们创建一个SerialPortHelper对象,然后创建一个新的QThread对象,将SerialPortHelper对象移动到该线程。接着,我们使用QObject::connect()函数连接SerialPortHelper对象和新线程的信号槽,以确保在新线程执行相关功能。 一旦SerialPortHelper对象被移动到新线程,调用线程的start()函数启动新线程的执行。此时,串口调试助手将在这个新线程独立地执行串口通信的相关功能。这样一来,主线程就不会因为串口通信而被阻塞,可以继续响应用户的操作。 需要注意的是,在使用moveToThread()函数时,要小心处理线程间的共享资源和对象销毁的问题,以避免潜在的竞态条件和内存泄漏。正确定义和管理线程的生命周期对于保证应用程序的稳定性和性能至关重要。 综上所述,通过将串口调试助手对象移动到一个新的线程执行,结合Qt的多线程机制,可以实现在进行串口通信时保持界面的响应性和流畅性。这种方式在开发需要串口通信的应用程序时非常有用。 ### 回答2: Qt是一个跨平台的C++框架,用于开发图形界面以及实现各种应用程序。其的多线程和串口调试助手是Qt常用的功能之一。 在Qt,多线程是为了提高程序的性能和响应速度而设计的。通过使用线程,可以将复杂耗时的任务放在独立的线程运行,不影响主线程的运行。这样可以保证程序的界面依然流畅,并且可以更好地处理输入输出和资源共享。 而串口调试助手则是为了帮助开发人员在Qt进行串口通信调试而设计的工具。串口通信是一种常见的通信方式,可以通过串口与其他硬件设备进行通信。在Qt,可以使用QSerialPort来实现串口通信。通过串口调试助手,开发人员可以方便地发送和接收串口数据,进行相关的调试和测试。 有时,可能需要将串口调试助手的功能放在独立的线程运行。这样可以确保在串口调试过程,界面不会被阻塞,保证程序的流畅运行。使用Qt的QObject::moveToThread函数可以实现将对象移动到指定的线程运行。这样,串口调试助手就可以在独立的线程处理串口数据的发送和接收,而不会影响主线程的运行。 总结起来,Qt的多线程和串口调试助手是为了提高程序性能、实现串口通信调试而设计的功能。通过合理使用线程和移动对象到指定线程,可以更好地实现程序的并发和异步处理,提高程序性能和可靠性。 ### 回答3: Qt的多线程机制可以用于在后台执行耗时的任务,避免阻塞主线程。串口调试助手可以通过将串口操作放在单独的线程执行,从而实现在调试期间不阻塞主界面的功能。 使用Qt的多线程功能,我们可以通过将串口操作相关的代码放在一个QObject,然后将该的实例移动到一个新的线程执行。具体步骤如下: 1. 创建一个QObject,例如SerialPortWorker,用于执行串口操作。在该,我们可以编写打开串口、写入数据、读取数据等串口操作的代码。 2. 在主线程创建一个QThread对象,例如SerialPortThread。 3. 创建SerialPortWorker的实例,并通过调用QObject::moveToThread()函数将该对象移动到SerialPortThread线程执行。这样做可以确保串口操作在后台线程执行,不会阻塞主界面。 4. 通过调用SerialPortThread的start()函数,启动线程。 5. 当需要进行串口操作时,可以通过发送信号的方式通知SerialPortWorker对象执行具体的串口操作。 这样,当我们需要进行串口调试时,只需通过发送信号的方式,实现与串口相关的操作,而不会影响主界面的响应。 需要注意的是,在子线程执行GUI相关的操作是不允许的,因此,如果需要在串口调试助手更新界面的数据,可以通过信号槽机制将相关的数据传递给主线程,由主线程更新界面的显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值