Qt 官方示例 | 了解文件读写,看这个例子就够了

大家好,我是老吴,一枚勤劳的嵌入式底层劳动人民。

我又双叒叕来分享 Qt 的学习心得了。

学习 Qt 的最佳途径是阅读官方的手册和示例,

今天要分享的是 Qt 官方提供的示例:notepad。

notepad 是一个简易文本编辑器:

点击查看大图

它一个支持新建、打开、保存、复制、粘贴、剪切、撤销、重做等功能的迷你型文本编辑器,类似 Gedit。

源码文件:

notepad/
├── images
│   ├── bold.png
│   ├── copy.png
│   ├── create.png
│   ├── cut.png
│   ├── edit_redo.png
│   ├── edit_undo.png
│   ├── exit.png
│   ├── font.png
│   ├── info.png
│   ├── italic.png
│   ├── new.png
│   ├── open.png
│   ├── paste.png
│   ├── pencil.png
│   ├── print.png
│   ├── save_as.png
│   ├── save.png
│   └── underline.png
├── main.cpp
├── notepad.cpp
├── notepad.h
├── notepad.pro
├── notepad.qrc
└── notepad.ui

下面快速地说明一下如何实现这个小工具, let's go.

正文目录:

1. 新建 Qt Widgets Application
2. 利用 Qt Designer 设计界面
3. 实现 New / Open / Save 文件的功能
4. 相关参考
5. 好书推荐:《就因为没时间,才什么都能办到》

1. 新建 Qt Widgets Application

在 Qt Creator 里 点击,

File > New File or Project > Applications > Qt Widgets Application > Choose:

点击查看大图

以 QMainWindow 作为基类,子类名为 Notepad:

新建完成后会得到下列文件:

notepad/
├── main.cpp
├── notepad.cpp
├── notepad.h
├── notepad.pro
└── notepad.ui

notepad.cpp 和 notepad.h 是 Notepad Widget 对应的类的源代码。

notepad.ui 则是 Notepad Widget 对应的 UI 界面文件。

运行效果:

此时只有跟 QMainWindow 一样的界面,还没有任何编辑器相关的功能。

2. 利用 Qt Designer 设计界面

Notepad 的界面分为 4 部分:

点击查看大图
  1. 菜单栏,用 QMenuBar 实现;
  2. 工具栏,用 QToolBar 实现;
  3. 文本编辑框,用 QTextEdit 实现;
  4. 状态栏,用 QstatusBar 实现;

本文不会讲解 Notepad 的所有功能,而是以下面 3 个功能为例:

  • 创建文件
  • 打开文件
  • 保存文件

只要这 3 个功能的实现逻辑理清楚,实现整个 Notepad 肯定也没有问题。

在 Qt Designer 里:

  • 修改菜单栏,添加 File 菜单项
  • 修改工具栏,添加 New、Open、Save Action
  • 添加编辑框

运行效果:

此时的菜单栏和工具栏里按键并没有任何功能。

3. 实现 New / Open / Save 文件的功能

在 Qt 里用 Action 这个概念来简化菜单栏和工具栏的的编程,

每一个菜单项都会有自己的 Action,开发者可以在 Qt Designer 里的 Action Editor 里定制 Action。

当用户点击某个菜单项时,就会发出 QAction::triggered 信号,我们需要为其设置对应的槽函数以实现对应的业务功能。

绑定信号和槽:

// 文件:notepad.cpp
Notepad::Notepad(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Notepad)
{
    ...
    connect(ui->actionNew, &QAction::triggered, this, &Notepad::newDocument);
    connect(ui->actionOpen, &QAction::triggered, this, &Notepad::open);
    connect(ui->actionSave, &QAction::triggered, this, &Notepad::save);
}

实现新建文件的功能

// 文件:notepad.h
class Notepad : public QMainWindow
{
    ...
private slots:
    void newDocument();
    void open();
    void save();

private:
    Ui::Notepad *ui;
    QString currentFile;
};

currentFile 用于保存当前文件的路径名。

void Notepad::newDocument()
{
    currentFile.clear();
    ui->textEdit->setText(QString());
    setWindowTitle("new File *");
}

创建新文件的过程很简单,就是清空文本框。

运行效果:

实现保存文件的功能

// 文件:notepad.cpp
void Notepad::save(){
    QString fileName;

    // 如果前面没有保存过,则询问用户保存在哪里
    if (currentFile.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this"Save");
        currentFile = fileName;
    } else {
        fileName = currentFile;
    }

    // 将文本框中的文本写到文件中
    QFile file(fileName);
    [...]
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();
}

Qt 提供了 QFile 类用于进行文件操作。

QFile 类本身就有读写文件的接口,但是一般用 QTextStream or QDataStream 来读写文件会更加方便。

另外:

  • 处理临时文件可以使用 QTemporaryFile,
  • 获取文件信息可以使用 QFileInfo,
  • 处理目录可以使用 QDir,
  • 监视文件和目录变化可以使用 QFileSystemWatcher。

运行效果:

实现打开文件的功能

// 文件:notepad.cpp
void Notepad::open(){
    // 用户选择要打开的文件
    QString fileName = QFileDialog::getOpenFileName(this"Open the file");
    QFile file(fileName);
    [...]

    currentFile = fileName;
    setWindowTitle(fileName);

    // 用文本流将文件内容读到文本框中
    QTextStream in(&file);
    QString text = in.readAll();
    ui->textEdit->setText(text);
    file.close();
}

用上面的代码里可以看出,Qt 里的文本流操作非常简单。

运行效果:

到此,这个 Notepad 示例的 核心功能就实现完毕啦。感兴趣的小伙伴们请自行阅读 Qt example 里的完整代码吧。

文件 IO 是编程世界里非常重要的一环,在 Qt 的许多示例里都要用到这一块知识点,这里我们先初步地了解一下 QTextStream ,后续需要在更多的示例中练习 Qt 的 IO 操作。

相关参考

《Qt 官方文档》:

  • Creating Main Windows in Qt Designer
  • File and Datastream Functions

《C++ GUI Qt4 编程 (第二版)》

《Qt5 编程入门 (第二版)》

《Qt Creator 快速入门》

思考技术,也思考人生

要学习技术,更要学习如何生活

好书推荐:

《就因為「沒時間」,才什麼都能辦到》

作者:吉田穗波

2004年 取得名古屋大学研究所博士学位,妇产科医师。在工作和家庭多头奔忙的情况下,反而让她因有感于「若要改变现状,只能积极提升自己的程度」,而兴起再进修的念头。从申请入学哈佛,准备考试到录取,只花半年时间!2008 年带着三岁,一岁和一个月大的三个女儿,与丈夫一起前往波士顿,两年取得哈佛学位。

豆瓣评分:8.0,790人评价

点击查看大图

能收获什么?

  • 不一样的时间观念;
  • 实用的时间管理方法;
  • 积极的心理建设;
  • 接受无序的状态;
  • 接受事情只做了一部分的情况;
  • 抓大放小,请别人来帮助自己处理非核心任务;

你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。

觉得文章对你有价值,不妨 在看 + 分享

推荐阅读:

专辑 | Linux 驱动开发

专辑 | Linux 系统编程

专辑 | 每天一点 C

专辑 | Qt 入门

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容