「Qt」文件读写操作

0、引言

        我们知道 C 和 C++ 都提供了文件读写的类库,不过 Qt 也有一套自己的文件读写操作;本文主要介绍 Qt 中进行文件读写操作的类 —— QFile

1、QFileDialog 文件对话框

        一般的桌面应用程序,当我们想要打开一个文件时,通常会弹出一个文件对话框。在 Qt 中,文件对话框使用 QFileDialog 类实现。

        QFileDialog 类允许用户遍历文件系统,以便选择一个或多个文件或目录。

        最简单的创建 QFileDialog 的方法是使用静态函数:

fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home", tr("Image Files (*.png *.jpg *.bmp)"));

        tr() 是 Qt 中的一个函数,用于将字符串标记为可翻译的字符串。这个函数的作用是在运行时,根据配置在 Qt Linguist 工具中的翻译,将输入字符串翻译成适当的语言。

        这意味着,如果您的应用程序支持多种语言,并且在 Qt Linguist 工具中配置了相应的翻译,那么这些字符串将在运行时被翻译成用户选择的语言。

        在上面的例子中,我们使用静态方法创建了一个模态 QFileDialog(什么是 模态对话框?)。该对话框初始显示 "/home" 目录中的内容,并显示与字符串 "Image files (*.png *.jpg *.bmp)" 中给出的模式匹配的文件。文件对话框的父窗口设置为 this,窗口标题设置为 "Open Image"

        如果你想要使用多个过滤器,请用 两个分号 分隔每一个过滤器。例如:

"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"

        如果您想要不使用任何文件过滤器,请直接传递空字符串。或者传递

"All Files (*)"

        (了解更多...)

        在上面的例子中我们可以尝试使用 QFileDialog 选择一个文件并将 fileName 打印到单行文本框,最终实现效果类似于下图:

文件对话框

2、QFile

        QFileDialog 只是帮助我们完成了获取文件的绝对路径(什么是 绝对路径(以 Windows 系统为例)?)的工作;接下来才是要进行文件读写的操作。在 Qt 中,文件读写通常与 QFile 类相关。

        💬 有关 QFile 的用法,还请读者参考 QFile 的官方文档,这里笔者不再赘述。下面主要介绍 QFileDialog 类配合 QFile 类的使用案例:

2.1、QFile 读操作

        以下代码展示了 QFileDialog 类配合 QFile 类打开并读取一张图片文件(我们在与 QPushButton::clicked 信号关联的槽函数中读取图片文件):

//点击“打开”按钮,弹出文件选择对话框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home" , tr("Image Files (*.png *.jpg *.bmp *.svg)"));//将路径放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//只读模式打开文件file.open(QIODevice::ReadOnly);//全部读取QByteArray bytes = file.readAll();//生成 QImage 实例QImage image = QImage::fromData(bytes);//生成 QPixmap 实例并显示在 QLabel 控件上ui->label->setPixmap(QPixmap::fromImage(image));//关闭文件file.close();
});

        使用 QFileDialog 配合 QFile,我们可以做到在运行时选择并读取图片文件:

读取图片文件并显示


        此外,我们还可以尝试使用 QFileDialog 配合 QFile 打开文本文件,只需略微修改上面示例代码中的槽函数即可:

  •  在 Linux(Ubuntu) 下,你可以使用如下命令创建文本文件:
    touch filename.txt
  • 创建完成后,在其中编辑一些字符,保存后就可以使用如下命令查看该文本文件的字符编码格式:
    file filename.txt# 如果文本文件中只有英文字符,则编码格式为 ASCII;
    # 如果带有中文字符,则编码格式为 UTF-8 Unicode。
  • 使用如下命令转换文本文件的字符编码格式(参考链接):
    sudo iconv -f 'utf-8' -t 'gbk' filename.txt > GbkText.txt
//点击“打开”按钮,弹出文件选择对话框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Text File"), "/home" , tr("Text Files (*.txt)"));//将路径放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//只读模式打开文件file.open(QIODevice::ReadOnly);//全部读取QByteArray bytes = file.readAll();//在 QLabel 文件上显示文本ui->label->setText(bytes);//关闭文件file.close();
});

        需要注意的是,QLabel::SetText() 方法接受一个 QString 类型的参数,而在上面的示例代码中我们传递了一个字节数组作为参数。

        巧合的是,QString 类提供了一个接受 QByteArray 类型的构造函数,这意味着这里会发生一次隐式转换将 QByteArray 类型转换为 QString 类型。不过,这个构造函数的转换将会使用 UTF-8 格式解码字符串。

        这样的隐式转换可能会导致一些问题,特别是当你的文本文件不是 UTF-8 格式编码时:

文本文件编码问题
两个文本文件内容一致,但 'GBK' 字符编码格式文件会显示乱码

        为了避免这样的问题,我们可以尝试使用一些 Qt 中专门用于编码和解码文本的类,比如 QTextCodec(在 Qt 5.15 过后已经部分弃用)和 QStringConverter 类;或者使用流来读取文件(使用流的时候,默认情况下,QTextStream 假设文件以 UTF-8 编码;但这可以使用QTextStream::setEncoding() 来改变)。

2.2、QFile 写操作

        除了读操作,我们还可以使用 QFileDialog 类配合 QFile 类打开并向文件中写入数据。下面是一个打开文本文件并向其中追加新的文本的示例,同样略微修改上面示例代码中的槽函数即可:

//点击“打开”按钮,弹出文件选择对话框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Text File"), "/home" , tr("Text Files (*.txt)"));//将路径放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//以追加的模式打开文件file.open(QIODevice::Append);//写数据file.write("这是我写入的文本!\n");//关闭文件file.close();//重新以只读方式打开文件file.open(QIODevice::ReadOnly);QByteArray data;//当没有到达文件末尾时while(!file.atEnd()){//按行读取data += file.readLine();}ui->label->setText(data);//关闭文件file.close();
});

下面是运行效果:

QFile 写操作

3、QFileInfo 文件信息

        QFileInfo 提供了文件在文件系统中的名称和位置(路径)、访问权限以及是目录还是符号链接等信息,还有文件的大小、最后修改/读取时间等信息。此外,QFileInfo 也可以用来获取关于 Qt 资源的信息。

        QFileInfo 可以指向具有相对或绝对文件路径的文件。绝对文件路径以目录分隔符 "/" 开头(或在 Windows 上以驱动器规格开头)。相对文件名以目录名或文件名开头,并指定相对于当前工作目录的路径。绝对路径的一个例子是字符串 "/tmp/quartz"。相对路径可能看起来像 "src/fatlib"。可以使用函数 isRelative() 检查 QFileInfo 使用的是相对文件路径还是绝对文件路径。您可以调用 makeAbsolute() 函数将 QFileInfo 的相对路径转换为绝对路径。

⚠️ 注意:以冒号(:)开头的路径总是被认为是绝对路径,因为它们表示一个 QResource

        QFileInfo 处理的文件是在构造函数中设置的(或者后续使用 setFile() 设置)。使用 exists() 查看文件是否存在并使用 size() 获取其大小。

        文件的类型通过 isFile()isDir()isSymLink() 获得。symLinkTarget() 函数提供了符号链接指向的文件的名称。

        在 Unix(包括 macOS 和 iOS)上,该类中的属性获取器函数返回目标文件的时间和大小等属性,而不是符号链接的时间和大小等属性,这是因为 Unix 透明地处理符号链接。使用 QFile 打开符号链接可以有效地打开链接的目标。例如:

#ifdef Q_OS_UNIXQFileInfo info1("/home/bob/bin/untabify");
info1.isSymLink();          // returns true
info1.absoluteFilePath();   // returns "/home/bob/bin/untabify"
info1.size();               // returns 56201
info1.symLinkTarget();      // returns "/opt/pretty++/bin/untabify"QFileInfo info2(info1.symLinkTarget());
info2.isSymLink();          // returns false
info2.absoluteFilePath();   // returns "/opt/pretty++/bin/untabify"
info2.size();               // returns 56201#endif

        在 Windows 上,快捷方式(.lnk 文件)目前被视为符号链接。与 Unix 系统一样,属性获取器返回目标文件的大小,而不是 .lnk 文件本身。此行为已被弃用,可能会在 Qt 的未来版本中删除,之后 .lnk 文件将被视为常规文件。

#ifdef Q_OS_WINQFileInfo info1("C:\\Users\\Bob\\untabify.lnk");
info1.isSymLink();          // returns true
info1.absoluteFilePath();   // returns "C:/Users/Bob/untabify.lnk"
info1.size();               // returns 63942
info1.symLinkTarget();      // returns "C:/Pretty++/untabify"QFileInfo info2(info1.symLinkTarget());
info2.isSymLink();          // returns false
info2.absoluteFilePath();   // returns "C:/Pretty++/untabify"
info2.size();               // returns 63942#endif

        文件名称的元素可以使用 path()fileName() 提取。fileName() 的部分可以用 baseName()suffix() 或 completeSuffix() 提取。QFileInfo 对象到由 Qt 类创建的目录将不会有尾随文件分隔符。如果您希望在自己的文件信息对象中使用尾随分隔符,只需在构造函数或 setFile() 给出的文件名后附加一个。

        文件的日期由 birthTime()lastModified()lastRead()fileTime() 返回。通过 isReadable()isWritable()isExecutable() 获取文件的访问权限信息。文件的所有权可以从 owner()ownerId()group()groupId() 中获得。您可以使用 permission() 函数在单个语句中检查文件的权限和所有权。

⚠️ 注意:在 NTFS 文件系统上,出于性能原因,默认情况下禁用所有权和权限检查。要启用它,包括以下行:

extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;

然后通过对 qt_ntfs_permission_lookup 加 1 和减 1 来打开和关闭权限检查。

qt_ntfs_permission_lookup++;     //启用检查
qt_ntfs_permission_lookup--;     //再次关闭检查

⚠️ 注意:由于这是一个非原子全局变量,所以只有在除主线程以外的任何线程启动之前或除主线程以外的每个线程结束之后,才可以对 qt_ntfs_permission_lookup 进行递增或递减操作。


        下面是一个 QFileDialog 类配合 QFileInfo 类获取文件信息的代码示例,同样略微修改 2.1 小节示例代码中的槽函数即可:

//点击“打开”按钮,弹出文件选择对话框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), "/home", tr("All Files (*)"));//将路径放到 LineEdit 中ui->lineEdit->setText(fileName);QFileInfo info(fileName);QString str = "path() = " + info.path() + "\n"+ "filePath() = " + info.filePath() + "\n"+ "fileName() = " + info.fileName() + "\n"+ "baseName() = " + info.baseName() + "\n"+ "suffix() = " + info.suffix() + "\n"+ "completeSuffix() = " + info.completeSuffix() + "\n"+ "birthTime() = " + info.birthTime().toString();    //toString()方法可指定日期输出格式ui->label->setText(str);
});

💬 在打印文件的日期信息时,可以指定输出的格式,比如:

info.birthTime().toString("yyyy/MM/dd hh:mm:ss"); // 2023/08/16 21:12:34

(参考 QDateTimetoString() 方法了解更多)

运行效果:

QFileInfo 获取文件信息

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

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

相关文章

php+echarts实现数据可视化实例

效果&#xff1a; 代码&#xff1a; php <?php include(includes/session.inc); include(includes/SQL_CommonFunctions.inc); ?> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv&quo…

OpenLayers入门,OpenLayers加载google街景地图

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解OpenLayers加载google街景地图,无需科学上网,也可以正常访问瓦片。 二、依赖和使用 "ol": "^6.15.1"使用npm安装依赖npm install ol@6.15.1使用Yarn安装依赖yarn add olvue中如何使用: vue项…

FastApi-1-结合sql 增/查demo

目录 FastAPI学习记录项目结构部分接口/代码展示感受全部代码 FastAPI学习记录 fastapi已经学习有一段时间&#xff0c;今天抽时间简单整理下。 官网介绍&#xff1a; FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;使用 Py…

SpringBoot的配置文件以及日志设置

在使用SpringBoot开发的过程中我们通常会用到配置文件来设置配置信息 以及使用日志来进行记录我们的操作&#xff0c;方便我们对错误的定位 配置文件的作用在于&#xff1a;设置端口&#xff0c;设置数据库连接信息&#xff0c;设置日志等等 在SpringBoot中&#xff0c;配置…

Linux系统编程:通过System V共享内存实现进程间通信

目录 一. 共享内存实现进程间通信的原理 二. 共享内存相关函数 2.1 共享内存的获取 shmget / ftok 2.2 共享内存与进程地址空间相关联 shmat 2.3 取消共享内存与进程地址空间的关联 shmdt 2.4 删除共享内存 shmctl 2.5 通信双方创建共享内存代码 三. 共享内存实现进程间…

承接各种设计

小弟985研究生毕业&#xff0c;目前攻读读博士&#xff0c;可做各种设计&#xff0c;包括但不限于Matlab 电力电子/电气工程&#xff0c;matlab/simulink 电气专业仿真MATLAB 电气工程专业&#xff0c;matlab建模 电力电子&#xff0c;电气工程&#xff0c;电力系统&#xff0c…

vue echarts macd指标 完整代码

1 逻辑 给指定的series两个对象 两个对象有相同的xAxisIndex: 2,yAxisIndex: 2, 不同的data {name: "",type: "line",data: data1,xAxisIndex: 2,yAxisIndex: 2,},{name: "",type: "bar",data: data2,xAxisIndex: 2,yAxisIndex: 2,},…

Mac M2 Pro安装使用Cocoapods

Mac Pro M2安装使用Cocoapods 在新公司要做iOS开发&#xff0c;所以在新电脑上安装Cocoapods 在升级gem&#xff0c;sudo gem update --system&#xff0c;和安装cocoapods时都遇到如下的提示&#xff1a; ERROR: While executing gem ... (Errno::EPERM)Operation not per…

Linux下安装nodejs

1、下载nodejs 点击前往&#xff1a;Download | Node.js 2、解压 tar -xvf node-v18.16.0-linux-x64.tar.xz mv node-v18.16.0-linux-x64/ /usr/local/nodejs 3、 建立软链接 此时的bin文件夹中已经存在node以及npm&#xff0c;如果你进入到对应文件的中执行命令行一点问题…

现代C++:使用 shared_from_this 防止 this 提前被释放

首先概括一下shared_from_this的作用&#xff1a;可以在类的成员函数中直接通过this得到指向当前所在对象的shared_ptr的智能指针&#xff0c;具体操作如下。 使用方法 设需要提供shared_from_this方法的类为C0定义为类&#xff0c;首先需要将C0定义为 std::enable_shared_fr…

mysql 02 数据库的约束

为防止错误的数据被插入到数据表&#xff0c;MySQL中定义了一些维护数据库完整性的规则&#xff1b;这些规则常称为表的约束。常见约束如下&#xff1a; 主键约束 主键约束即primary key用于唯一的标识表中的每一行。被标识为主键的数据在表中是唯一的且其值不能为空。这点类似…

前后端分离------后端创建笔记(10)用户修改

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

Spring Boot实现第一次启动时自动初始化数据库流程详解

随着互联网的发展项目中的业务功能越来越复杂&#xff0c;有一些基础服务我们不可避免的会去调用一些第三方的接口或者公司内其他项目中提供的服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素。 在测试阶段可能没有什么异常情况&#xff0c;但上线后可能会出…

设计HTML5文本

网页文本内容丰富、形式多样&#xff0c;通过不同的版式显示在页面中&#xff0c;为用户提供最直接、最丰富的信息。HTML5新增了很多文本标签&#xff0c;它们都有特殊的语义&#xff0c;正确使用这些标签&#xff0c;可以让网页文本更严谨、更符合语义。 1、通用文本 1.1、标…

算法竞赛备赛之搜索与图论训练提升,暑期集训营培训

目录 1.DFS和BFS 1.1.DFS深度优先搜索 1.2.BFS广度优先搜索 2.树与图的遍历&#xff1a;拓扑排序 3.最短路 3.1.迪杰斯特拉算法 3.2.贝尔曼算法 3.3.SPFA算法 3.4.多源汇最短路Floy算法 4.最小生成树 4.1.普利姆算法 4.2.克鲁斯卡尔算法 5.二分图&#xff1a;染色法…

7. CSS(四)

目录 一、浮动 &#xff08;一&#xff09;传统网页布局的三种方式 &#xff08;二&#xff09;标准流&#xff08;普通流/文档流&#xff09; &#xff08;三&#xff09;为什么需要浮动&#xff1f; &#xff08;四&#xff09;什么是浮动 &#xff08;五&#xff09;浮…

OpenAI全球招外包大军,手把手训练ChatGPT取代码农 ; 码农:我自己「杀」自己

目录 前言 OpenAI招了一千多名外包人员&#xff0c;训练AI学会像人类一样一步步思考。如果ChatGPT「学成归来」&#xff0c;码农恐怕真的危了&#xff1f; 码农真的危了&#xff01; 当时OpenAI也说&#xff0c;ChatGPT最合适的定位&#xff0c;应该是编码辅助工具。 用Cha…

计算机竞赛 opencv 图像识别 指纹识别 - python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器视觉的指纹识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c;适…

Vue引入Echarts报错 import * as echarts from “echarts“;

项目场景&#xff1a; 已经下载好echarts cnpm i echarts Vue引入Echarts import echarts from echarts mounted() {this.myChart echarts.init(document.querySelector(.right))this.myChart.setOption({title: {text: 消费列表,left: center},...问题描述 原因分析&#…

【100天精通python】Day38:GUI界面编程_PyQT从入门到实战(中)

目录 专栏导读 4 数据库操作 4.1 连接数据库 4.2 执行 SQL 查询和更新&#xff1a; 4.3 使用模型和视图显示数据 5 多线程编程 5.1 多线程编程的概念和优势 5.2 在 PyQt 中使用多线程 5.3 处理多线程间的同步和通信问题 5.3.1 信号槽机制 5.3.2 线程安全的数据访问 Q…