Qt基础终结篇:从文件操作到多线程异步UI,深度解析核心要点

news2025/6/2 21:35:08

文章目录

  • 前言
  • 一、QFileDialog 文件对话框
  • 二、QFileInfo 文件信息类
  • 三、QFile 文件读写类
  • 四、UI与耗时操作:避免UI卡顿与程序未响应
  • 五、多线程
  • 六、异步刷新与线程通信
  • 总结


前言

上一篇文章,我们已经把qt的基础知识讲解的差不多了。本文我们将继续进行qt的学习,并且一口气把qt的基础知识讲解完。大家可以根据目录的指引来快速获取自己需要的知识和内容,那么文章就从这里开始吧。


一、QFileDialog 文件对话框

QFileDialog 是 Qt 框架中用于提供标准文件选择对话框的类。它允许用户选择一个文件进行打开(读取)或保存(写入)。

核心特点:

纯界面类: QFileDialog 本身不执行文件的实际读写操作。它只负责提供一个用户界面,让用户选择文件路径。一旦用户选择了文件,它会返回该文件的路径字符串,后续的文件操作(如打开、读取、写入)需要由应用程序自行处理。
静态方法: 最常用的文件选择功能通过其静态方法提供,这意味着你不需要创建 QFileDialog 的实例就可以直接调用它们。

常用静态函数:
QFileDialog 提供了方便的静态方法来弹出“打开文件”或“保存文件”的对话框。

  1. getOpenFileName() - 弹出“打开文件”对话框

功能: 允许用户选择一个已存在的文件进行打开(通常是读取)。

QString QFileDialog::getOpenFileName(
    QWidget * parent = 0,
    const QString & caption = QString(),
    const QString & dir = QString(),
    const QString & filter = QString()
) [static]

返回值:
如果用户选择了一个文件并点击“打开”,则返回所选文件的完整路径字符串。
如果用户取消了对话框(例如点击“取消”按钮或关闭窗口),则返回一个空字符串。

  1. getSaveFileName() - 弹出“保存文件”对话框

功能: 允许用户指定一个文件路径来保存数据。用户可以选择一个现有文件进行覆盖,或者输入一个新文件名来创建新文件。

QString QFileDialog::getSaveFileName(
    QWidget * parent = 0,
    const QString & caption = QString(),
    const QString & dir = QString(),
    const QString & filter = QString()
) [static]

返回值:
如果用户指定了一个文件路径并点击“保存”,则返回所指定文件的完整路径字符串。
如果用户取消了对话框,则返回一个空字符串。

参数详解(适用于 getOpenFileName 和 getSaveFileName)

QWidget * parent = 0

类型: QWidget 指针
作用: 指定文件对话框的父窗口。
影响:
如果指定了父窗口,对话框将以模态(modal)方式显示,并居中于父窗口。这意味着用户必须先关闭文件对话框才能与父窗口进行交互。
如果为 0(默认值),对话框将作为顶级窗口显示,并且可能不会居中于任何特定窗口。
建议: 强烈建议指定父窗口,以提供更好的用户体验和窗口管理。

const QString & caption = QString()

类型: QString
作用: 设置文件对话框的标题栏文本。
默认值: 空字符串,此时系统会提供默认标题(例如“打开文件”或“保存文件”)。
示例: “选择图片文件”,“保存文档”

const QString & dir = QString()

类型: QString
作用: 指定对话框打开时最初显示的目录路径。
默认值: 空字符串,此时对话框通常会从应用程序的当前工作目录(或用户上次访问的目录,取决于操作系统和Qt版本)开始。
示例: “C:/Users/YourName/Documents”,“/home/user/images”
注意: 如果指定的目录不存在,对话框可能会回退到默认行为。

const QString & filter = QString()

类型: QString
作用: 定义文件类型过滤器,用于限制用户可以看到和选择的文件类型。
默认值: 空字符串,表示显示所有文件类型。
格式: 过滤器字符串由一个或多个过滤器项组成,每个项的格式为:“描述 (.扩展名1 .扩展名2);;描述2 (.扩展名3)"
描述: 用户在下拉菜单中看到的文本。
.扩展名: 匹配的文件扩展名。可以使用通配符
;;: 用于分隔多个过滤器项。
示例:
"图片文件 (
.png .jpg .jpeg);;文本文件 (.txt);;所有文件 (.
)"
"C++ 源文件 (
.cpp .h);;Qt 项目文件 (.pro)”
注意: 过滤器只影响显示的文件,用户仍然可以通过手动输入文件名来选择不符合过滤器的文件(在某些操作系统上)。

代码示例
代码包


二、QFileInfo 文件信息类

QFileInfo 类用于获取文件的各种信息,例如文件是否存在、文件大小、上次修改时间等。它提供了多种成员函数来访问这些属性。

构造函数

QFileInfo::QFileInfo(const QString &file)

参数: file - 文件的完整路径(包括文件名)。
说明: 使用指定的文件路径构造一个 QFileInfo 对象。在构造之后,你可以使用该对象的成员函数来查询文件的各种属性。
常用成员函数

bool QFileInfo::exists() const

返回值: 如果文件或目录存在,则返回 true;否则返回 false。
说明: 用于检查由 QFileInfo 对象表示的文件或目录是否存在于文件系统中。

qint64 QFileInfo::size() const

返回值: 文件的字节大小。如果文件不存在或无法访问,则返回 0。
说明: 返回文件的大小,单位是字节。对于目录,此函数通常返回 0。

QDateTime QFileInfo::lastModified() const

返回值: 一个 QDateTime 对象,包含文件的上次修改日期和时间。如果文件不存在或无法访问,则返回一个无效的 QDateTime 对象。
说明: 获取文件的最后修改时间戳。QDateTime 对象可以进一步格式化或用于时间比较。

代码示例

代码包


三、QFile 文件读写类

QFile类是Qt中用于文件操作的核心类,它间接继承自QIODevice类。QIODevice类是Qt所有IO类的基类,提供了许多读写的基础接口。

核心功能概述
QFile提供了方便的文件创建、打开、读写和关闭操作。它通过其基类QIODevice继承了通用的IO操作接口,并为文件系统特有的行为(如文件路径、权限等)提供了封装。

相关函数
以下是QFile和其基类中常用的一些函数:

  1. 构造函数
QFile::QFile(const QString & name)

作用: 构造一个QFile对象。
参数: name (const QString &) - 指定要操作的文件的路径和名称。
备注: 构造函数只是创建了QFile对象并设置了文件路径,并不会立即打开文件。

  1. 文件流操作
bool QIODevice::open(OpenMode mode)

作用: 打开文件流。这是在读写文件之前必须调用的函数。
参数: mode (OpenMode) - 指定打开文件的模式。OpenMode是一个枚举类型,可以组合使用(例如:QIODevice::ReadOnly | QIODevice::Text)。
常用模式举例:
QIODevice::ReadOnly: 只读模式。文件必须存在。
QIODevice::WriteOnly: 只写模式。如果文件不存在则创建,如果存在则清空内容。
QIODevice::ReadWrite: 读写模式。
QIODevice::Append: 追加模式。写入的数据会添加到文件末尾。
QIODevice::Truncate: 清空模式。打开文件时会清空文件内容。
QIODevice::Text: 文本模式。在Windows上,将\r\n转换为\n,反之亦然。
返回值: bool - 如果成功打开文件则返回true,否则返回false。
备注: 建议在使用后检查返回值,以确保文件成功打开。

void QIODevice::close()

作用: 关闭文件流。释放文件资源。
备注: 在文件操作完成后,务必调用此函数来关闭文件,以避免资源泄露或数据丢失。

  1. 数据读取
QByteArray QIODevice::read(qint64 maxSize)

作用: 从文件流中读取指定最大字节数的数据。
参数: maxSize (qint64) - 要读取的最大字节数。
返回值: QByteArray - 包含读取到的数据的字节数组。如果达到文件末尾或发生错误,返回的QByteArray可能小于maxSize或为空。
备注: 该函数会尝试读取最多maxSize个字节,但可能因为文件剩余内容不足或到达文件末尾而读取更少的数据。

qint64 QIODevice::bytesAvailable() const

作用: 返回流中当前可供读取的剩余字节数。
返回值: qint64 - 可用的字节数。
备注: 在读取文件时,可以使用此函数来判断是否还有数据可读,或者一次性读取所有剩余数据。

  1. 数据写入
qint64 QIODevice::write(const QByteArray & byteArray)

作用: 将QByteArray中的数据写入文件流。
参数: byteArray (const QByteArray &) - 要写入的数据。
返回值: qint64 - 实际写入的字节数。如果发生错误,可能返回-1或小于byteArray.size()的值。
备注: 在写入后,应检查返回值以确保所有数据都已成功写入。

  1. 缓冲区操作
bool QFileDevice::flush()

作用: 清空文件设备的内部写缓冲区,将所有缓存的数据强制写入底层设备(例如硬盘)。
返回值: bool - 如果刷新成功则返回true,否则返回false。
备注: 写入操作通常是先写入内存缓冲区,再由操作系统或文件系统异步写入磁盘。flush()可以强制将数据立即写入磁盘,这在确保数据持久性(例如在关键操作后或程序退出前)时非常有用。

代码示例
代码包


四、UI与耗时操作:避免UI卡顿与程序未响应

  1. 主线程(UI线程)的职责:

程序启动时,默认只有一个线程,即主线程(也称为UI线程)。
主线程的核心职责是处理所有Qt基础事件和UI操作,确保用户界面的流畅响应。

  1. 耗时操作对主线程的影响:

当耗时较长的操作(例如:读写大文件、复杂的计算、网络请求等)在主线程中执行时,主线程会被这些操作“占用”或“阻塞”。
被阻塞的主线程无法及时处理UI事件(如点击、滚动、窗口重绘等),导致用户界面出现卡顿、假死现象。
如果阻塞时间过长,操作系统会认为程序失去了响应,并可能弹出“程序未响应”的提示窗口,严重影响用户体验。

  1. 解决方案:分离耗时操作到子线程:

为了保持UI的流畅和程序的响应性,解决卡顿问题的根本方法是:将所有耗时较长的操作从主线程中分离出来。
这些耗时操作应该被移到独立的“子线程”中执行。
子线程在后台默默工作,而主线程则继续专注于UI事件的处理,从而确保用户界面的持续响应和良好的用户体验。


五、多线程

QThread 类是 Qt 提供的用于多线程编程的类。它封装了平台相关的线程API,提供了一个方便、跨平台的接口来创建和管理线程。

QThread 类核心函数:

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

描述: 强制当前线程睡眠 msecs 毫秒。这是一个静态函数,可以在任何线程中调用,使该线程进入休眠状态。常用于模拟耗时操作。

void QThread::run() [virtual protected]

描述: 这是子线程的起始点。当你调用 QThread::start() 函数后,QThread 内部会自动调用这个 run() 函数。你需要继承 QThread 类并覆盖(override)这个函数,将所有需要在子线程中执行的耗时操作放在这个 run() 函数的实现中。

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

描述: 启动子线程。调用此函数后,QThread 会创建一个新的操作系统线程,并在该线程中执行你的 run() 函数。priority 参数可以设置线程的优先级,通常保持默认即可。

创建并开启一个子线程的详细步骤:

在Qt Creator中创建新的C++ Class文件:

在Qt Creator的“项目”视图中,右键点击你的项目名称。
选择“添加新文件…”。
在弹出的对话框中,选择“C++ Class”。

配置类信息:
通常会提示你输入类名、基类等信息。
类名: 例如 MyThread (你可以根据自己的需求命名)。
基类 (Base Class): 选择 QThread。
确保勾选“头文件”和“源文件”的选项,Qt Creator会自动为你生成 mythread.h 和 mythread.cpp (如果你的类名是MyThread)。

完成类创建:
直接点击“完成”按钮。现在你的项目中会多了 mythread.h 和 mythread.cpp 两个文件。

代码示例
代码包


六、异步刷新与线程通信

在实际开发中,特别是涉及到用户界面(UI)的应用,异步刷新是一个至关重要的概念。它解决了在UI线程上执行耗时操作所导致的界面冻结问题。而实现异步刷新的核心,就是主线程和子线程之间的通信。

  1. 为什么需要异步刷新?
    主线程不能执行耗时操作:

主线程(通常也称为UI线程)负责处理用户交互、绘制UI界面等任务。
如果主线程执行耗时操作(如网络请求、数据库查询、大文件读写、复杂计算),它会被阻塞,导致UI无响应、用户体验极差,甚至可能被操作系统判定为“应用程序无响应”(ANR)。

UI操作是线程不安全的: 多数UI框架(如Android的View体系,Java Swing/AWT,.NET WinForms/WPF)规定,所有对UI组件的修改必须在主线程上执行。这是为了避免并发访问UI组件时出现数据不一致或绘制错误。

子线程不能执行UI操作:
子线程的创建是为了执行耗时操作,从而不阻塞主线程。
直接在子线程中操作UI组件会导致应用程序崩溃、行为异常或不可预测的UI状态。

  1. 线程通信的本质:父对象与子对象的通信
    正如内容中提到的,“主线程往往是子线程的父对象,因此线程通信问题本质上就是父对象和子对象的通信问题。”这是一种非常形象且准确的理解。

子线程(“子对象”)执行任务并报告结果: 子线程启动后,执行它的耗时任务。任务完成后,它需要将结果(或者任务完成的状态)通知给主线程。
主线程(“父对象”)接收通知并更新UI: 主线程接收到子线程的通知后,根据通知的内容,在主线程上执行相应的UI更新操作。

代码示例
代码包

示例:多线程文件拷贝器
代码包


总结

本文作为Qt基础知识的“终结篇”,系统地梳理并深入讲解了Qt应用程序开发中的几个关键模块:QFileDialog文件对话框、QFileInfo文件信息类、QFile文件读写类,以及至关重要的多线程编程。文章首先详细介绍了如何使用QFileDialog进行文件选择,以及QFileInfo获取文件元数据。随后,深入探讨了QFile的文件打开、读写操作及其缓冲机制。为了解决UI卡顿和程序未响应问题,文章重点阐述了多线程的必要性,详细讲解了QThread的使用方法,并强调了主线程与子线程间异步刷新和通信的本质。通过详细的理论解析和代码示例,旨在帮助读者掌握Qt中文件操作的实用技巧和多线程编程的核心思想,为构建响应迅速、用户体验良好的Qt应用打下坚实基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2393958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

山洪灾害声光电监测预警解决方案

一、方案背景 我国是一个多山的国家,山丘区面积约占国土面积的三分之二。每年汛期,受暴雨等因素影响,极易引发山洪和泥石流。山洪、泥石流地质灾害具有突发性、流速快、流量大、物质容量大和破坏力强等特点,一旦发生,将…

【Rust模式与匹配】Rust模式与匹配深入探索与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

electron安装报错处理

electron安装报错 解决方法: 修改 C:\Users\用户名.npmrc下配置文件 添加代码 electron_mirrorhttps://cdn.npmmirror.com/binaries/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/最后代码 registryhtt…

NHANES指标推荐:CQI

文章题目:The impact of carbohydrate quality index on menopausal symptoms and quality of life in postmenopausal women 中文标题:碳水化合物质量指数对绝经后妇女更年期症状和生活质量的影响 发表杂志:BMC Womens Health 影响因子&…

【从零开始学习QT】快捷键、帮助文档、Qt窗口坐标体系

目录 Qt Creator 中的快捷键 使用帮助文档 Qt 窗口坐标体系 QT专栏:QT_uyeonashi的博客-CSDN博客 Qt Creator 中的快捷键 • 注释:ctrl / • 运行:ctrl R • 编译:ctrl B • 字体缩放:ctrl 鼠标滑轮 • 查找&am…

基于stm32的多旋翼无人机(Multi-rotor UAV based on stm32)

由于一直在调试本项目,好久没有发文章,最近本项目的PID调试初见成效!开始正文前首先感谢各位粉丝的支持,以及对本项目技术上支持的老师以及师兄,谢谢你们! 对应源码及文件:源码及文件下载 基于…

实验分享|基于sCMOS相机科学成像技术的耐高温航空涂层材料损伤检测实验

1实验背景 航空发动机外壳的耐高温涂层材料在长期高温、高压工况下易产生微小损伤与裂纹,可能导致严重安全隐患。传统光学检测手段受限于分辨率与灵敏度,难以捕捉微米级缺陷,且检测效率低下。 某高校航空材料实验室,采用科学相机…

RAG混合检索:倒数秩融合RRF算法

文章目录 检索增强生成 (RAG)倒数秩融合在 RAG 中的工作原理RRF 背后的数学直觉检索增强生成 (RAG) RAG 是自然语言处理中的一种强大技术,结合了基于检索的模型和生成模型的优势。 如果检索器未能从检索器中获取相关文档,则精度较低,幻觉的可能性会增加。 有些查询适合…

2011肠衣问题

1 D类竞赛题目---具体题目 D题 天然肠衣搭配问题 天然肠衣(以下简称肠衣)制作加工是我国的一个传统产业,出口量占世界首位。肠衣经过清洗整理后被分割成长度不等的小段(原料),进入组装工序。 传统的生产…

RG3000网关构建5G LAN智慧工厂智能制造

在工业4.0与智能制造的趋势下,传统制造业正前后往智慧工厂转型升级。在转型过程中,高效、稳定、灵活的网络通信是实现设备互联互通、数据实时交互与智能决策的基础。智联物联RG3000网关,凭借其融合5G通信技术、WiFi6无线传输、边缘计算能力与…

webrtc初了解

1. webrtc的简介 一、WebRTC 是什么? Web Real-Time Communication(网页实时通信),是浏览器原生支持的实时音视频通信技术,无需安装插件或客户端,可直接在浏览器之间实现点对点(P2P&#xff09…

[STM32学习笔记(九)]CubeMX项目使用系统定时器SysTick的中断服务函数进行定时

有很多文章说明了由于HAL_Delay()函数的本质是系统定时器计数,通过全局变量uwTick的不断增加实现的比较延迟。调用HAL_Delay()函数会阻塞其他工作,因此在外设ISR进程调用该延迟时,要特别小心。 因此,现在考虑,既然系统…

将ipynb文件转换为markdown格式文件

文章目录 将ipynb文件转换为markdown格式文件nbconvert 包安装nbconvert 使用 将ipynb文件转换为markdown格式文件 有时候,我们需要把Jupyter notebook的.ipynb格式文件转换为markdown格式.md,便于使用。 那么,我们可以通过安装nbconvert包&a…

Vulnhub_Zico2_wp

一、信息收集 1、主机发现 arp-scan -l 2、端口扫描 nmap -sS -sV 192.168.66.144 nmap -p- -Pn -sC -sV -n 192.168.66.144 whatweb -v 192.168.66.144 这里开放了3个端口,先80端口拿去目录,然后测试下22端口有没有什么未授权之类的,然后…

【玩转腾讯混元大模型】腾讯混元大模型AIGC系列产品深度体验

【玩转腾讯混元大模型】腾讯混元大模型AIGC系列产品深度体验 腾讯推出的系列AI产品:混元大模型、大模型图像创作引擎、大模型视频创作引擎、腾讯元宝,共同构成了一个强大的AI生态系统;凭借腾讯自研的大规模预训练技术和先进的自然语言处理、计…

Attention Is All You Need论文阅读笔记

Attention is All You Need是如今机器学习研究者必读的论文,该文章提出的Transformer架构是如今很多机器学习项目的基础,说该文章极大推动了机器学习领域的研究也不为过。 但这么重要,也是必读的文章对初学者来说其实并不友好,很多…

如何制作全景VR图?

全景VR图,特别是720度全景VR,为观众提供一种沉浸式体验。 全景VR图能够捕捉场景的全貌,还能将多个角度的图片或视频无缝拼接成一个完整的全景视角,让观众在虚拟环境中自由探索。随着虚拟现实(VR)技术的飞速…

Flask与PostgreSQL交互教程

目录 1. 项目结构2. 环境准备2.1 安装依赖2.2 使用Docker启动PostgreSQL 3. 数据库配置3.1 环境变量配置3.2 数据库连接配置 4. 定义数据库模型5. 实现API接口5.1 创建用户5.2 获取所有用户5.3 获取单个用户5.4 更新用户5.5 删除用户 6. 运行应用7. API测试7.1 创建用户7.2 获取…

XJTU-SY轴承振动数据集的json自封装

1.最终形式的形式 不用再去翻文档找对应的故障类型,采样率等信息了,所有的信息自包含在.json文件里,15个测试例,一个测试例对应一整个.json文件。 {"dataset": {"name": "XJTU-SY_Bearing_Datasets&quo…

Spring AI 系列2: Advisors增强器简介

一、Advisors简介 1.1 Advisors定义 Advisors 是在 AI 应用程序中处理请求和响应的拦截器。我们可以使用它们为提示流程设置额外的功能。例如,可以建立聊天历史、排除敏感词或为每个请求添加额外的上下文。 Spring AI的Advisor,本质上是一个拦截…