Skip to content

正点原子QT之文本读写 ​

11. 文本读写 ​

11.1 QFile 读写文本 ​

QFile 是一个读写文本、二进制文件和资源的 I/O 设备。 QFile 可以自己使用,也可以更方便地与 QTextStream 或 QDataStream 一起使用。
可以使用 exists()检查文件是否存在,并使用 remove()删除文件。用 open()打开文件,用 close()关闭文件,用 flush()刷新文件。
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

案例:读写文本 ​

打开后,文本的内容如下,可以进行修改,修改后点击关闭就会写入到此文件里

cpp
#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;

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

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

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

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

    return true;
}

void MainWindow::closeFile()
{
    /* 检测打开按钮是否可用,不可用时,说明已经打开了文件 */
    if (!openPushButton->isEnabled()) {
        /* 获取textEdit的文本内容 */
        QString str = textEdit->toPlainText();

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

        /* 转换为字节数组 */
        QByteArray strBytes = str.toUtf8();

        /* 写入文件 */
        file.write(strBytes, strBytes.length());

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

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

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

11.2 QTextStream 读写文本 ​

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

案例:文本流读写文本 ​

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

cpp
#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);
    }
}