「Qt」文件读写操作

news2024/11/17 3:28:48

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);

    //使用文件的绝对路径实例化 QFile
    QFile 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);

    //使用文件的绝对路径实例化 QFile
    QFile 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);

    //使用文件的绝对路径实例化 QFile
    QFile 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_UNIX

QFileInfo 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_WIN

QFileInfo 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.coloradmin.cn/o/887235.html

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

相关文章

ArcGIS Pro基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例全流程科研能力提升

目录 第一章 入门篇 GIS理论及ArcGIS Pro基础 第二章 基础篇 ArcGIS数据管理与转换 第三章 数据编辑与查询、拓扑检查 第四章 制图篇 地图符号与版面设计 第五章 空间分析篇 ArcGIS矢量空间分析及应用 第六章 ArcGIS栅格空间分析及应用 第七章 影像篇 遥感影像处理 第八…

Azure如何启用网络观察应用程序

文章目录 基础概念介绍实操 基础概念介绍 Azure中的网络观察应用程序是一种用于监视和诊断Azure网络的工具。它提供了一种集中管理和监控网络流量、连接性和性能的方式。网络观察应用程序能够提供网络流量分析、连接监视、性能监视和故障诊断等功能,用于帮助管理员…

Layui列表表头去掉复选框改为选择

效果&#xff1a; 代码&#xff1a; // 表头复选框去掉改为选择 $(".layui-table th[data-field"0"] .layui-table-cell").html("<span>选择</span>");

【git】初次使用git上传代码到github远程仓库

目录 0.前言1.新建代码库2.添加SSH公钥2.1 前置准备2.2 Git 基本信息设置2.3 添加SSH Key 3.本地仓库上传到github3.1 建立本地仓库并初始化3.2 初始化仓库3.3 建立本地与github上新建项目链接3.4 同步github新建项目到本地3.5 添加本地文件到缓存区3.6 为上传文件添加注释3.7 …

PyQt5编写可视化程序GB/T 34986-2017 产品加速试验方法(B 5.5 湿度试验)

GB/T 34986-2017 产品加速试验方法&#xff08;B 5.5 湿度试验&#xff09; 阿伦纽斯模型-温度&#xff08;Arrhenius Mode) 温度公式 AF exp{(Ea/K)[(1/Tu)-(1-Tt)]} 举例 AF exp{[0.68/(8.61738510e-5)][[1/(27325)]-[1/(273105)]]} ≈271.9518 AF 为加速因子 RHs 施加应力…

CentOS系统环境搭建(十五)——CentOS安装Kibana

centos系统环境搭建专栏&#x1f517;点击跳转 关于Elasticsearch的安装请看CentOS系统环境搭建&#xff08;十二&#xff09;——CentOS7安装Elasticsearch。 CentOS安装Kibana 1.下载 &#x1f517;https://www.elastic.co/downloads/past-releases/kibana-7-17-12 若你是…

【Rust】Rust学习 第十四章进一步认识 Cargo 和 Crates.io

本章会讨论 Cargo 其他一些更为高级的功能&#xff0c;我们将展示如何&#xff1a; 使用发布配置来自定义构建将库发布到 crates.io使用工作空间来组织更大的项目从 crates.io 安装二进制文件使用自定义的命令来扩展 Cargo Cargo 的功能不止本章所介绍的&#xff0c;关于其全…

音视频学习-音视频基础

文章目录 一、 音视频录制原理二、音视频播放原理三、图像基础概念1.像素2.分辨率3.位深4.帧率5.码率6.Stride跨距 四、RGB、YUV1.RGB2.YUV1. 4:4:4格式2. 4:2:2格式3. 4:2:0格式4. 4:2:0数据格式对比 3.RGB和YUV的转换4.YUV Stride对齐问题 五、视频的主要概念1.基本概念2.I P…

python控制obs实现无缝切换场景!obs-websocket-py

前言 最近一直在研究孪生数字人wav2lip。目前成果可直接输入高清嘴型&#xff0c;2070显卡1分钟音频2.6分钟输出。在直播逻辑上可以做到1比1.3这样&#xff0c;所以现在开始研究直播。在逻辑上涉及到了无缝切换&#xff0c;看到csdn上有一篇文章还要vip解锁。。。那自己研究吧…

C# API 文档注释规范

C# API 文档注释规范 1. 命名空间注释(namespace)2. summary3. remarks and para4. param5. returns6. example and code7. exception8. typeparam 最近在开发工作中需要实现 API 帮助文档&#xff0c;如果根据所写的代码直接重写 API 帮助文档将会是意见非常大的工作量&#x…

Linux:shell函数

目录 一、基本格式 二、查看函数 三、删除函数 四、函数的返回值 五、函数的传参数 六、函数的作用范围 ​七、函数的递归 在编写脚本时&#xff0c;有些脚本可以反复使用&#xff0c;可以调用函数来解决 语句块定义成函数约等于别名 函数使用方法&#xff1a; 定义函…

ZooKeeper的应用场景(集群管理、Master选举)

5 集群管理 随着分布式系统规模的日益扩大&#xff0c;集群中的机器规模也随之变大&#xff0c;因此&#xff0c;如何更好地进行集群管理也显得越来越重要了。 所谓集群管理&#xff0c;包括集群监控与集群控制两大块&#xff0c;前者侧重对集群运行时状态的收集&#xff0c;后…

LabVIEW开发商用罗非鱼池水质控制系统设计

LabVIEW开发商用罗非鱼池水质控制系统设计 养鱼是一种水产养殖形式&#xff0c;其中鱼类在围栏内养殖&#xff0c;作为食物出售。这些围栏栖息地用于养殖全球大约一半的鱼类消费。罗非鱼是一种适合食品生产和经营的鱼类&#xff0c;因为它们能够快速繁殖。然而&#xff0c;为了…

【苹果Imessage推信软件】在服务器端,您可以保存设备令牌,并将其用于向特定设备发送推送通知

推荐内容IMESSGAE相关 作者✈️IMEAE推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAE推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAE推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAE推荐内容3.日历推 *** …

Linux -- 进阶 Autofs自动挂载服务 实验详解

服务端创建共享目录&#xff0c; 客户端实现自动挂载 第一步 &#xff1a; 客户端&#xff0c;服务端 均关闭安全软件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootnode1 ~]# setenforce 0 [rootnode1 ~]# systemctl stop firewalld 第二…

windows安装go,以及配置工作区,配置vscode开发环境

下载安装go 我安装在D:\go路径下配置环境变量 添加GOROOT value为D:\go修改path 添加%GOROOT%\bin添加GOPATH value为%USERPROFILE%\go 其中GOPATH 是我们自己开发的工作区&#xff0c;其中包含三个folder bin,pkg,以及src&#xff0c;其中src为我们编写代码的位置 配置vscod…

算法通关村第4关【青铜】| 栈基础

1. 栈基础 栈的特征&#xff1a; 存取受限的线性表后进先出 栈的操作&#xff1a; push()pop()peek()empty() 2.数组实现栈 限制数组的存取规则&#xff0c;实现后进先出。注意数组边界的处理 public class Stack1<T> {private Object[] stack;private int top;//…

RPA机器人《国网电力》电力行业实施案例-基层减负 提质增效

背景&#xff1a;随着国网战略目标加速落地&#xff0c;数字化转型和精益化管理深化推进&#xff0c;各供电公司亟待突破精细化管控不深入、执行标准不够统一、系统数据不够融通等制约工作质效提升的能力瓶颈&#xff0c;针对这些问题&#xff0c;决定引入诸如RPA、OCR等技术&a…

深入Redis线程模型

目录 1.前言 2.Redis为什么快&#xff1f; 3.Redis 为何选择单线程&#xff1f; 3.1可维护性 3.2并发处理 3.3性能瓶颈 4.Reactor设计模式 5.Redis4.0前 单线程模型 - Event Loop 6.Redis4.0后 多线程异步任务 7.Redis6.0后 多线程网络模型 1.前言 这篇文章我们主要围绕…

快速搭建图书商城小程序的简易流程与优势

很多人喜欢阅读电子书&#xff0c;又有很多人依旧喜欢实体书&#xff0c;而实体书店拥有一个图书商城小程序便成为了满足用户需求的理想选择。如果您也想进入这一充满潜力的领域&#xff0c;但担心开发难度和复杂流程&#xff0c;别担心&#xff01;您能做到快速搭建一个专业、…