Qt----文本读写

文本读写

在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本章介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。

一、QFile读写文本

QFile 类提供了读取和写入文件的接口。在嵌入式里如果需要读写文件,最简单的方法就是用 Qfile。

QFile 是一个读写文本、二进制文件和资源的 I/O 设备。QFile 可以自己使用,也可以更方便地与 QTextStream 或 QDataStream 一起使用。
文件名通常在构造函数中传递,但它可以在任何时候使用setFileName()设置。不支持使用其他分隔符(例如’’)。所以在 Windows、 Linux 或者 Mac 里文件的路径都是用’/’。不能看到
Windows 的路径是’’,我们就可以在写入的文件路径里添加这个’’。不管操作系统是什么,QFile的文件分隔符都是’/’。

可以使用 exists()检查文件是否存在,并使用 remove()删除文件。(更高级的文件系统相关操作由 QFileInfo 和 QDir 提供。)用 open()打开文件,用 close()关闭文件,用 flush()刷新文件。通常使用QDataStream 或 QTextStream 读写数据,但也可以调用 QIODevice 继承的函数 read()、readLine()、readAll()、write()。QFile 还继承 getChar()、putChar()和 ungetChar(),它们一次只处理一个字符。文件的大小由 size()返回。可以使用 pos()获取当前文件位置,也可以使用 seek()移动到新的文件位置。如果已经到达文件的末尾,则atEnd()返回 true。

QFile::open()函数打开文件时需要传递 QIODevice::OpenModeFlag 枚举类型的参数,决定文件以什么方式打开,QIODevice::OpenModeFlag 类型的主要取值如下:

 QIODevice::ReadOnly:以只读方式打开文件,用于载入文件。
 QIODevice::WriteOnly:以只写方式打开文件,用于保存文件。
 QIODevice::ReadWrite:以读写方式打开。
 QIODevice::Append:以添加模式打开,新写入文件的数据添加到文件尾部。
 QIODevice::Truncate:以截取方式打开文件,文件原有的内容全部被删除。
 QIODevice::Text:以文本方式打开文件,读取时“\n”被自动翻译为换行符,写入时字符串结束符会自动翻译为系统平台的编码,如 Windows 平台下是“\r\n”。

这些取值可以组合,例如 QIODevice::ReadOnly | QIODevice::Text 表示以只读和文本方式打开文件。

使用 QFile 对一个文本文件的操作流程是以下这样的。
在这里插入图片描述

1. 应用实例

例 01_qfile,读写文本(难度:简单)。项目路径为 Qt/2/01_qfile。2 是代表第二篇的例程父目录。

在头文件“mainwindow.h”具体代码如下。

1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 #include <QTextEdit>
6 #include <QFile>
7 #include <QVBoxLayout>
8 #include <QHBoxLayout>
9 #include <QPushButton>
10
11 class MainWindow : public QMainWindow
12 {
13 Q_OBJECT
14
15 public:
16 MainWindow(QWidget *parent = nullptr);
17 ~MainWindow();
18
19 private:
20 /* 用于读取文件后显示 */
21 QTextEdit *textEdit;
22
23 /* QFile 类型对象 */
24 QFile file;
25
26 /* 水平布局 */
27 QHBoxLayout *hBoxLayout;
28
29 /* 垂直布局 */
30 QVBoxLayout *vBoxLayout;
31
32 /* 水平布局 Widget */
33 QWidget *hWidget;
34
35 /* 垂直布局 Widget */
36 QWidget *vWidget;
37
38 /* 打开文件按钮 */
39 QPushButton *openPushButton;
40
41 /* 关闭文件按钮 */
42 QPushButton *closePushButton;
43
44 private slots:
45
46 /* 打开文本文件 */
47 bool openFile();
48
49 /* 关闭文本文件 */
50 void closeFile();
51 };
52 #endif // MAINWINDOW_H

在源文件“mainwindow.cpp”具体代码如下。

#include "mainwindow.h"
#include <QFileDialog>
#include <QDebug>
1 MainWindow::MainWindow(QWidget *parent)
2 : QMainWindow(parent)
3 {
4 /* 设置窗口的位置与大小 */
5 this->setGeometry(0, 0, 800, 480);
6
7 /* 布局设置 */
8 textEdit = new QTextEdit();
9 vBoxLayout = new QVBoxLayout();
10 hBoxLayout = new QHBoxLayout();
11 vWidget = new QWidget();
12 hWidget = new QWidget();
13 openPushButton = new QPushButton();
14 closePushButton = new QPushButton();
15
16 /* 设置两个按钮的大小 */
17 openPushButton->setMinimumHeight(50);
18 openPushButton->setMaximumWidth(120);
19 closePushButton->setMinimumHeight(50);
20 closePushButton->setMaximumWidth(120);
21
22 /* 设置两个按钮的文本 */
23 openPushButton->setText("打开");
24 closePushButton->setText("关闭");
25
26 /* 设置关闭按钮为不可用属性,需要打开文件才设置为可用属性 */
27 closePushButton->setEnabled(false);
28
29 /* 水平布局 */
30 hBoxLayout->addWidget(openPushButton);
31 hBoxLayout->addWidget(closePushButton);
32 hWidget->setLayout(hBoxLayout);
33
34 /* 垂直布局 */
35 vBoxLayout->addWidget(textEdit);
36 vBoxLayout->addWidget(hWidget);
37 vWidget->setLayout(vBoxLayout);
38
39 /* 居中 */
40 setCentralWidget(vWidget);
41
42 /* 信号槽连接 */
43 connect(openPushButton, SIGNAL(clicked()),
44 this, SLOT(openFile()));
45 connect(closePushButton, SIGNAL(clicked()),
46 this, SLOT(closeFile()));
47 }
48
49 MainWindow::~MainWindow()
50 {
51 }
52
53 bool MainWindow::openFile()
54 {
55 /* 获取文件的路径 */
56 QString fileName = QFileDialog::getOpenFileName(this);
57
58 /* 指向文件 */
59 file.setFileName(fileName);
60
61 /* 判断文件是否存在 */
62 if (!file.exists())
63 return false;
64
65 /* 以读写的方式打开 */
66 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
67 return false;
68
69 /* 读取文本到 textEdit */
70 textEdit->setPlainText(file.readAll());
71
72 /* 设置打开按钮不可用,需要关闭再打开 */
73 openPushButton->setEnabled(false);
74
75 /* 设置关闭按钮为可用属性 */
76 closePushButton->setEnabled(true);
77
78 /* 关闭文件 */
79 file.close();
80
81 return true;
82 }
83
84 void MainWindow::closeFile()
85 {
86 /* 检测打开按钮是否可用,不可用时,说明已经打开了文件 */
87 if (!openPushButton->isEnabled()) {
88 /* 获取 textEdit 的文本内容 */
89 QString str = textEdit->toPlainText();
90
91 /* 以只读的方式打开 */
92 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
93 return;
94
95 /* 转换为字节数组 */
96 QByteArray strBytes = str.toUtf8();
97
98 /* 写入文件 */
99 file.write(strBytes, strBytes.length());
100
101 /* 清空 textEdit 的显示内容 */
102 textEdit->clear();
103
104 /* 关闭文件 */
105 file.close();
106
107 /* 重新设置打开和关闭按钮的属性 */
108 openPushButton->setEnabled(true);
109 closePushButton->setEnabled(false);
110 }
111 }

2. 程序运行效果

点击打开。
在这里插入图片描述
调用系统打开文件的窗口。选择项目路径下的“测试.txt”。
在这里插入图片描述
打开后,文本的内容如下,可以进行修改,修改后点击关闭就会写入到此文件里。本例仅仅用两个按钮和一个文本编辑框完成,内容简洁易懂。但是在实际项目里不是用 QPushButton来做打开文件和关闭文件的,一般设计于在菜单栏里用 QAction 来做。包括添加复制、粘贴、另存为、关闭、等等。可以仿照 Windows 里的记事本,用 Qt 写一个类似的软件完全可以。
在这里插入图片描述

二、QTextStream读写文本

QTextStream 类为读写文本提供了一个方便的接口,常与 QFile 结合使用。QTextStream 可以在 QIODevice、QByteArray 或 QString 上操作。使用 QTextStream 的流操作符,您可以方便地读写单词、行和数字。为了生成文本,QTextStream 支持字段填充和对齐的格式化选项,以及数字的格式化。看到 Stream 这个名词就知道,它与流操作有关,那么我们可以使用 C++的操作符“<<”和“>>”(流提取运算符和流插入运算符)进行操作流了。

1. 应用实例

例 02_qtextstream,文本流读写文本(难度:简单)。项目路径为 Qt/2/02_qtextstream。QTextStream 的例子与 QFile 的一样,只是在 QFile 的例子里加入了 QTextStream。

在头文件“mainwindow.h”具体代码如下。

/******************************************************************
Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
* @projectName   01_qfile
* @brief         mainwindow.h
* @author        Deng Zhimao
* @email         1252699831@qq.com
* @net           www.openedv.com
* @date          2021-03-27
*******************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QFile>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 用于读取文件后显示 */
    QTextEdit *textEdit;

    /* QFile类型对象 */
    QFile file;

    /* 水平布局 */
    QHBoxLayout *hBoxLayout;

    /* 垂直布局 */
    QVBoxLayout *vBoxLayout;

    /* 水平布局Widget */
    QWidget *hWidget;

    /* 垂直布局Widget */
    QWidget *vWidget;

    /* 打开文件按钮 */
    QPushButton *openPushButton;

    /* 关闭文件按钮 */
    QPushButton *closePushButton;

private slots:

    /* 打开文本文件 */
    bool openFile();

    /* 关闭文本文件 */
    void closeFile();
};
#endif // MAINWINDOW_H

在源文件“mainwindow.cpp”具体代码如下。

/******************************************************************
Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
* @projectName   02_qtextstream
* @brief         mainwindow.cpp
* @author        Deng Zhimao
* @email         1252699831@qq.com
* @net           www.openedv.com
* @date          2021-03-27
*******************************************************************/
#include "mainwindow.h"
#include <QFileDialog>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置窗口的位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 布局设置 */
    textEdit = new QTextEdit();
    vBoxLayout = new QVBoxLayout();
    hBoxLayout = new QHBoxLayout();
    vWidget = new QWidget();
    hWidget = new QWidget();
    openPushButton = new QPushButton();
    closePushButton = new QPushButton();

    /* 设置两个按钮的大小 */
    openPushButton->setMinimumHeight(50);
    openPushButton->setMaximumWidth(120);
    closePushButton->setMinimumHeight(50);
    closePushButton->setMaximumWidth(120);

    /* 设置两个按钮的文本 */
    openPushButton->setText("打开");
    closePushButton->setText("关闭");

    /* 设置关闭按钮为不可用属性,需要打开文件才设置为可用属性 */
    closePushButton->setEnabled(false);

    /* 水平布局 */
    hBoxLayout->addWidget(openPushButton);
    hBoxLayout->addWidget(closePushButton);
    hWidget->setLayout(hBoxLayout);

    /* 垂直布局 */
    vBoxLayout->addWidget(textEdit);
    vBoxLayout->addWidget(hWidget);
    vWidget->setLayout(vBoxLayout);

    /* 居中 */
    setCentralWidget(vWidget);

    /* 信号槽连接 */
    connect(openPushButton, SIGNAL(clicked()),
            this, SLOT(openFile()));
    connect(closePushButton, SIGNAL(clicked()),
            this, SLOT(closeFile()));
}

MainWindow::~MainWindow()
{
}

bool MainWindow::openFile()
{
    /* 获取文件的路径 */
    QString fileName = QFileDialog::getOpenFileName(this);

    /* 指向文件 */
    file.setFileName(fileName);

    /* 判断文件是否存在 */
    if (!file.exists())
        return false;

    /* 以读写的方式打开 */
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    /* 使用文本流读取文件 */
    QTextStream stream(&file);

    /* 读取文本到textEdit */
    textEdit->setPlainText(stream.readAll());

    /* 设置打开按钮不可用,需要关闭再打开 */
    openPushButton->setEnabled(false);

    /* 设置关闭按钮为可用属性 */
    closePushButton->setEnabled(true);

    /* 关闭文件 */
    file.close();

    return true;
}

void MainWindow::closeFile()
{
    /* 检测打开按钮是否可用,不可用时,说明已经打开了文件 */
    if (!openPushButton->isEnabled()) {

        /* 以只读的方式打开 */
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
            return;

        /* 用文本流读取文件 */
        QTextStream stream(&file);

        /* 获取textEdit的文本内容,转为字符串 */
        QString str = textEdit->toPlainText();

        /* 使用流提取运算符,写入文本流 */
        stream<<str;

        /* 清空textEdit的显示内容 */
        textEdit->clear();

        /* 关闭文件 */
        file.close();

        /* 重新设置打开和关闭按钮的属性 */
        openPushButton->setEnabled(true);
        closePushButton->setEnabled(false);
    }
}

2. 程序运行效果

与上面一样。使用 QFile 与 QTextStream 感觉例子看上去没区别。主要是 QTextStream 还支持字段填充和对齐的格式化选项,例子没有体现出来而已,等我们用到一些特性时还是有区别的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值