QT-系统(文件)

目录

记事本模拟

需求与技术选型

界面搭建:菜单与编辑区的组合

[文件 "打开" 功能:从路径选择到内容读取](#文件 “打开” 功能:从路径选择到内容读取)

[文件 "保存" 功能:从内容获取到文件写入](#文件 “保存” 功能:从内容获取到文件写入)

[QIODevice 家族与文件操作的扩展性](#QIODevice 家族与文件操作的扩展性)

总结与拓展

获取文件属性

[QFileInfo 是什么?](#QFileInfo 是什么?)

[QFileInfo 常用方法解析](#QFileInfo 常用方法解析)

[实战:用 QFileInfo 解析文件属性](#实战:用 QFileInfo 解析文件属性)

场景:选择文件后,打印其元信息

代码说明

总结


记事本模拟

在 Qt 开发中,文件操作和界面交互是非常基础且重要的能力。本文将通过打造一个简易记事本应用,带你深入理解 Qt 中如何实现文件的 "打开""保存" 功能,以及界面组件的联动逻辑。我们会基于 QIODevice 家族的 QFile 类来完成文件 IO,同时结合 QAction、QPlainTextEdit 等组件构建交互界面。

需求与技术选型

我们要实现的记事本功能很明确:

  • 界面上有 "文件" 菜单,包含 "打开""保存" 两个操作选项;
  • 支持通过文件对话框选择文件,读取文件内容到编辑区;
  • 支持将编辑区内容保存到指定文件。

技术选型

  • 界面框架:Qt 的 QMainWindow + QMenuBar + QPlainTextEdit,构建经典窗口应用结构;
  • 文件操作:QFile(属于 QIODevice 家族,用于本地文件读写)+ QFileDialog(文件选择对话框);
  • 事件联动:QAction + 信号槽机制,实现菜单操作与业务逻辑的绑定。

界面搭建:菜单与编辑区的组合

首先,我们需要构建应用的界面骨架 ------ 包含菜单的菜单栏,以及用于编辑文本的输入区域。

cpp 复制代码
// mainwindow.cpp 构造函数部分
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("记事本"); // 设置窗口标题

    // 1. 构建菜单栏与菜单
    QMenuBar* menubar = this->menuBar();
    QMenu* menu = new QMenu("文件");
    menubar->addMenu(menu);

    // 2. 构建"打开""保存"动作(QAction)
    QAction* a1 = new QAction("打开");
    QAction* a2 = new QAction("保存");
    menu->addAction(a1);
    menu->addAction(a2);

    // 3. 构建文本编辑区
    edit = new QPlainTextEdit();
    QFont font;
    font.setPixelSize(20); // 设置字体大小,提升可读性
    edit->setFont(font);
    this->setCentralWidget(edit); // 将编辑区设为窗口中心组件

    // 4. 信号槽绑定:动作触发时执行对应的业务函数
    connect(a1, &QAction::triggered, this, &MainWindow::handleAction1);
    connect(a2, &QAction::triggered, this, &MainWindow::handleAction2);
}

这段代码的核心是组件的分层组织:菜单栏作为顶层导航,文本编辑区作为内容载体,通过 QAction 把 "菜单点击" 和 "文件操作逻辑" 关联起来(信号槽机制的经典应用)。

文件 "打开" 功能:从路径选择到内容读取

"打开文件" 功能的流程是:选择文件路径 → 打开文件 → 读取内容 → 展示到编辑区 。我们通过 QFileDialog 选路径,QFile 做读写,步骤清晰且容错性强。

cpp 复制代码
void MainWindow::handleAction1()
{
    // 1. 弹出"打开文件"对话框,让用户选择文件
    QString path = QFileDialog::getOpenFileName(this);
    if (path.isEmpty()) return; // 用户取消选择,直接返回

    // 2. 把选中的文件路径显示到状态栏,方便用户确认
    QStatusBar* statusBar = this->statusBar();
    statusBar->showMessage("正在打开:" + path);

    // 3. 构造 QFile 对象并尝试打开(只读模式)
    QFile file(path);
    bool ret = file.open(QIODevice::ReadOnly);
    if (!ret) {
        // 打开失败时给用户提示
        statusBar->showMessage(path + " 打开失败!");
        return;
    }

    // 4. 读取文件全部内容
    QString text = file.readAll();

    // 5. 关闭文件(必须!否则会导致文件占用等问题)
    file.close();

    // 6. 将读取的内容设置到文本编辑区
    edit->setPlainText(text);
    statusBar->showMessage(path + " 打开成功!");
}

关键细节

  • QFileDialog::getOpenFileName 会弹出系统原生的文件选择框,用户选择后返回文件路径;
  • QFile::open 要指定打开模式(这里是 ReadOnly 只读),打开失败时需给用户明确提示;
  • 读取完成后必须关闭文件,否则会造成资源泄漏或文件异常。

文件 "保存" 功能:从内容获取到文件写入

"保存文件" 的流程是:选择保存路径 → 打开文件 → 写入内容 → 关闭文件。和 "打开" 逻辑对称,但要注意写入模式的选择。

cpp 复制代码
void MainWindow::handleAction2()
{
    // 1. 弹出"保存文件"对话框,让用户选择保存路径
    QString path = QFileDialog::getSaveFileName(this);
    if (path.isEmpty()) return; // 用户取消选择,直接返回

    // 2. 把保存路径显示到状态栏
    QStatusBar* statusBar = this->statusBar();
    statusBar->showMessage("正在保存:" + path);

    // 3. 构造 QFile 对象并尝试打开(只写模式)
    QFile file(path);
    bool ret = file.open(QFile::WriteOnly);
    if (!ret) {
        statusBar->showMessage(path + " 打开失败!");
        return;
    }

    // 4. 获取编辑区的文本内容,并写入文件
    const QString& text = edit->toPlainText();
    file.write(text.toUtf8()); // 转成 UTF-8 编码写入,避免中文乱码

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

    statusBar->showMessage(path + " 保存成功!");
}

关键细节

  • QFileDialog::getSaveFileName 会处理 "文件不存在则创建" 的逻辑,无需手动判断;
  • 写入时用 WriteOnly 模式,若文件已存在会覆盖原有内容(如需追加可改用 Append 模式);
  • 文本编码要统一(这里用 toUtf8() 转 UTF-8),否则可能出现中文乱码。

QIODevice 家族与文件操作的扩展性

在 Qt 中,QFileQIODevice 的子类,而 QIODevice 是所有 IO 设备的抽象基类,它还包含了 QTcpSocket(网络套接字)、QBuffer(内存缓冲区)等子类。

这意味着我们的文件操作逻辑具有很强的扩展性 ------ 如果未来需要把 "记事本" 的内容通过网络发送(比如做一个 "云记事本"),只需把 QFile 替换成 QTcpSocket,底层的 openreadAllwrite 等接口可以无缝兼容。这种面向抽象类编程的设计,是 Qt 框架灵活性的体现。

总结与拓展

通过这个简易记事本的实现,我们掌握了 Qt 中界面构建、文件 IO、信号槽联动的核心流程:

  • 界面层:用 QMenuBarQAction 构建交互入口,QPlainTextEdit 承载内容;
  • 逻辑层:用 QFile + QFileDialog 完成本地文件的 "打开""保存",并通过状态栏给用户反馈;
  • 架构层:借助 QIODevice 的抽象设计,为功能扩展留下了空间。

获取文件属性

在 Qt 开发中,操作文件时不仅需要读写内容,还经常需要获取文件的元信息(如文件名、大小、类型、修改时间等)。Qt 提供的 QFileInfo 类就是为解决这个需求而生的,它可以让我们便捷地获取文件和目录的各种属性。本文将带你深入了解 QFileInfo 的常用方法和实际应用场景。

QFileInfo 是什么?

QFileInfo 是 Qt 框架中专门用于获取文件和目录信息的类。它可以帮助我们查询文件的文件名、大小、类型、创建时间、修改时间等元数据,让文件操作更加灵活和智能。

无论是普通文件还是目录,QFileInfo 都能轻松应对,是文件管理类应用(如文件浏览器、资源管理器)和需要文件元信息的业务场景(如日志分析、资源统计)的得力工具。

QFileInfo 常用方法解析

QFileInfo 提供了丰富的方法来获取文件的各种属性,以下是最常用的几个:

方法名 功能说明
isDir() 检查当前路径是否是目录
isExecutable() 检查文件是否是可执行文件
fileName() 获取文件名(不含路径)
completeBaseName() 获取完整的文件名(不含后缀)
suffix() 获取文件后缀名(如 "txt"、"exe")
completeSuffix() 获取完整的文件后缀(复杂后缀场景,如 "tar.gz")
size() 获取文件大小(字节数)
isFile() 判断是否是普通文件(非目录)
fileTime() 获取文件的创建时间、修改时间、最近访问时间等

实战:用 QFileInfo 解析文件属性

下面我们通过一个简单的示例,演示如何用 QFileInfo 获取并打印文件的各项属性。

场景:选择文件后,打印其元信息

我们通过 QFileDialog 让用户选择一个文件,然后用 QFileInfo 解析它的属性并打印。

cpp 复制代码
void Widget::on_pushButton_clicked()
{
    // 弹出文件选择对话框,让用户选择一个文件
    QString path = QFileDialog::getOpenFileName(this);
    if (path.isEmpty()) { // 用户取消选择,直接返回
        return;
    }

    // 构造 QFileInfo 对象,传入文件路径
    QFileInfo fileInfo(path);

    // 打印文件的各项属性
    qDebug() << "文件名:" << fileInfo.fileName();
    qDebug() << "文件后缀:" << fileInfo.suffix();
    qDebug() << "文件路径:" << fileInfo.path();
    qDebug() << "文件大小:" << fileInfo.size() << "字节";
    qDebug() << "是否为文件:" << fileInfo.isFile();
    qDebug() << "是否为目录:" << fileInfo.isDir();
    qDebug() << "是否可执行:" << fileInfo.isExecutable();
    qDebug() << "创建时间:" << fileInfo.fileTime(QFileInfo::CreationTime);
    qDebug() << "修改时间:" << fileInfo.fileTime(QFileInfo::ModificationTime);
}

代码说明

  1. 文件选择 :通过 QFileDialog::getOpenFileName 弹出文件选择框,获取用户选择的文件路径。
  2. 构造 QFileInfo :将文件路径传入 QFileInfo 构造函数,创建文件信息对象。
  3. 属性查询与打印 :通过 QFileInfo 的各种方法,分别获取文件名、后缀、路径、大小、类型、时间等信息,并通过 qDebug() 打印。

总结

QFileInfo 是 Qt 中处理文件元信息的 "瑞士军刀",它让我们摆脱了底层系统 API 的繁琐调用,以面向对象的方式轻松获取文件的各种属性。无论是简单的文件信息打印,还是复杂的文件类型校验、目录遍历,QFileInfo 都能提供简洁高效的解决方案。

相关推荐
云帆小二3 小时前
从开发语言出发如何选择学习考试系统
开发语言·学习
光泽雨3 小时前
python学习基础
开发语言·数据库·python
百***06014 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
jghhh014 小时前
基于幅度的和差测角程序
开发语言·matlab
fruge4 小时前
自制浏览器插件:实现网页内容高亮、自动整理收藏夹功能
开发语言·前端·javascript
曹牧5 小时前
Java中处理URL转义并下载PDF文件
java·开发语言·pdf
未来之窗软件服务5 小时前
幽冥大陆(二十二)dark语言智慧农业电子秤读取——东方仙盟炼气期
开发语言·windows·golang·东方仙盟·东方仙盟sdk
逐步前行5 小时前
C项目--羊了个羊(两关全)--含源码
c语言·开发语言
IMPYLH5 小时前
Lua 的 assert 函数
开发语言·笔记·junit·单元测试·lua
离离茶6 小时前
【笔记1-8】Qt bug记录:QListWidget窗口的浏览模式切换为ListMode后,滚轮滚动速度变慢
笔记·qt·bug