QT实现简易记事本

QT的Qmainwindow实现简易记事本,不带有UI界面。

1、功能展示

1、编辑文件时,文件名左上角有个"*",代表文件未保存

2、菜单栏有文件、编辑的选项

3、工具栏有保存、新建、打开、调节字体、调节颜色。

4、文件菜单中有,新建,保存、打开、另存为

5、编辑栏中有复制、剪切、粘贴、撤销、恢复

2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
#include <QFileDialog>
#include <QFile>
#include <QDebug>
#include <QMessageBox>
#include <QAction>
#include <QToolButton>
#include <QFileInfo>
#include <QFontDialog>
#include <QColorDialog>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void openFile();//文件的打开,给槽函数调用的
    void readFile(QString filePath);
    //自已添加的公有槽函数
public slots:
    void openActionSlots();
    void newActionSlots();
    void saveActionSlots();
    void saveasActionSlots();
    void copyActionSlots();
    void pasteActionSlots();
    void cutActionSlots();
    void undoActionSlots();
    void redoActionSlots();
//自已添加的私有成员变量(数据成员)
private:
    QString fileName;//保存文件的文件名
    QString filePath;//保存文件的绝对路径,一般用
    QTextEdit *text;//主体区域的多行文本
};
#endif // MAINWINDOW_H

3、mainwindow.cpp

#include "mainwindow.h"

#include <QAction>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //1.给窗口设置图标、标题
    this->setWindowIcon(QIcon(":/icons/icons/1.png"));
    this->fileName = "新建文本文档.txt";
    this->setWindowTitle(this->fileName);

    //2.给窗口添加菜单栏,工具栏、状态栏、主体区域
    QMenuBar *menu_bar = new QMenuBar(this);
    this->setMenuBar(menu_bar);

    QToolBar *tool_bar = new QToolBar(this);
    this->addToolBar(tool_bar);

    QStatusBar *status_bar = new QStatusBar(this);
    this->setStatusBar(status_bar);

    this->text = new QTextEdit(this);//因为这是一个记事本,所以主体区域是多行文本框
    this->setCentralWidget(this->text);

    //3.给菜单栏添加菜单,有两个菜单:文件、编辑
    QMenu *file_menu = new QMenu("文件(F)",this);
    menu_bar->addMenu(file_menu);


    QMenu *edit_menu = new QMenu("编辑(E)",this);
    menu_bar->addMenu(edit_menu);

    //4.1 给文件菜单添加动作   file_menu的功能(动作) 新建、打开、保存、另存为
    QAction *new_action = new QAction(this);
    new_action->setText("新建(N)");
    new_action->setIcon(QIcon(":/icons/icons/new.png"));
    new_action->setShortcut(QKeySequence::New);
    file_menu->addAction(new_action);

    QAction *open_action = new QAction(QIcon(":/icons/icons/open.png"),"打开(O)",this);
    open_action->setShortcut(QKeySequence::Open);
    file_menu->addAction(open_action);

    QAction *save_action = new QAction(QIcon(":/icons/icons/save.png"),"保存(S)",this);
    save_action->setShortcut(QKeySequence::Save);
    file_menu->addAction(save_action);

    QAction *saveas_action = new QAction("另存为(A)",this);
    saveas_action->setShortcut(QKeySequence::SaveAs);
    file_menu->addAction(saveas_action);

    //4.2 给编辑菜单添加动作  edit_menu的功能(动作) 复制、粘贴、剪切、撤销、恢复
    QAction *copy_action = new QAction(QIcon(":/icons/icons/copy.png"),"复制(C)",this);
    copy_action->setShortcut(QKeySequence::Copy);
    edit_menu->addAction(copy_action);

    QAction *paste_action = new QAction(QIcon(":/icons/icons/paste.png"),"粘贴(V)",this);
    paste_action->setShortcut(QKeySequence::Paste);
    edit_menu->addAction(paste_action);

    QAction *cut_action = new QAction(QIcon(":/icons/icons/cut.png"),"剪切(X)",this);
    cut_action->setShortcut(QKeySequence::Cut);
    edit_menu->addAction(cut_action);


    QAction *undo_action = new QAction("撤销(Z)",this);
    undo_action->setShortcut(QKeySequence::Undo);
    edit_menu->addAction(undo_action);


    QAction *redo_action = new QAction("恢复(Y)",this);
    redo_action->setShortcut(QKeySequence::Redo);
    edit_menu->addAction(redo_action);

    //4.3.1 给工具栏添加动作,便于快速实现某些功能 :新建、打开、保存
    tool_bar->addAction(new_action);
    tool_bar->addAction(open_action);
    tool_bar->addAction(save_action);

    //4.3.2 给工具栏添加工具按钮,有字体和颜色的按钮
    QToolButton *font_btn = new QToolButton(this);//创建字体按钮对象
    font_btn->setIcon(QIcon(":/icons/icons/font.png"));//给字体按钮对象设置图标
    tool_bar->addWidget(font_btn);//向工具栏中添加这个按钮,使用addWidget

    QToolButton *color_btn = new QToolButton(this);
    color_btn->setIcon(QIcon(":/icons/icons/color.png"));
    tool_bar->addWidget(color_btn);



    //5.信号与槽函数的关联,三种方式:1、QT5。   2、QT4。 3、匿名槽函数(C++11)。
    //信号是菜单栏的行为动作,点击
    connect(new_action,&QAction::triggered,this,&MainWindow::newActionSlots);
    connect(open_action,&QAction::triggered,this,&MainWindow::openActionSlots);
    connect(save_action,&QAction::triggered,this,&MainWindow::saveActionSlots);
    connect(saveas_action,&QAction::triggered,this,&MainWindow::saveasActionSlots);
    //对文档输入内容时,文档名称会有个'*'
    connect(this->text,&QTextEdit::textChanged,this,[=]()
    {
        this->setWindowTitle("*"+this->fileName);
    });
    //字体和颜色选择的信号和槽函数的关联,信号是工具按钮的点击,槽函数是匿名函数
    connect(font_btn,&QToolButton::clicked,this,[=]()
    {
        bool ok;
        QFont font =  QFontDialog::getFont(&ok,this);//获取字体
        this->text->setFont(font);//给文本设置字体
    });
    connect(color_btn,&QToolButton::clicked,this,[=]()
    {
        QColor color = QColorDialog::getColor(Qt::white,this);//获取颜色
        this->text->setTextColor(color);//给文本框的字体设置颜色
    });
    //对编辑菜单的信号和槽函数的关联  复制、粘贴、剪切、撤销、恢复
    connect(copy_action, &QAction::triggered, this, &MainWindow::copyActionSlots);
    connect(paste_action, &QAction::triggered, this, &MainWindow::pasteActionSlots);
    connect(cut_action, &QAction::triggered, this, &MainWindow::cutActionSlots);
    connect(undo_action, &QAction::triggered, this, &MainWindow::undoActionSlots);
    connect(redo_action, &QAction::triggered, this, &MainWindow::redoActionSlots);

    //connect(copy_action, &QAction::triggered, this->text, &QTextEdit::copy);

}

MainWindow::~MainWindow()
{
}

void MainWindow::openFile()
{
    //这是一个文件的绝对路径,不是单独的文件名
    this->filePath = QFileDialog::getOpenFileName(this,"打开","./","TXT(*.txt)");
    qDebug()<<this->filePath;
    //对文件进行操作,打开文件,读文件的全部内容,关闭文件
    QFile file(this->filePath);
    bool res = file.open(QFile::ReadOnly);
    if(res == true)
    {
        QByteArray data = file.readAll();//读文件中全部都内容,将其给多行文本区
        this->text->setText(data);
        file.close();//关闭文件
        //设置文件名为当前打开的文件名,将绝对路径的最后为文件名 back()或者last()获取分割后整个列表的最后一个值
        this->fileName = this->filePath.split("/").last();
        //设置给窗口标题
        this->setWindowTitle(this->fileName);
    }

}

void MainWindow::readFile(QString filePath)
{
    this->filePath = filePath;
    //对文件进行操作,打开文件,读文件的全部内容,关闭文件
    QFile file(this->filePath);
    bool res = file.open(QFile::ReadOnly);
    if(res == true)
    {
        QByteArray data = file.readAll();//读文件中全部都内容,将其给多行文本区
        this->text->setText(data);
        file.close();//关闭文件
        //获取到了文件名
        this->fileName = QFileInfo(this->filePath).fileName();
        //设置给窗口标题
        this->setWindowTitle(this->fileName);
    }

}

void MainWindow::newActionSlots()
{
    //QTextDocument *  是否怎么样,优先去找is开头并且函数类型是bool
    bool res = this->text->document()->isModified();
    //首先判断是否修改过文件
    if(res == true)//若修改了,则分情况讨论。是否要保存修改的文件,再新建文件
    {
        int ret = QMessageBox::question(this,"记事本","是否对修改进行保存",
                              QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
        if(ret == QMessageBox::Yes)
        {
            qDebug()<<"保存";
            this->saveActionSlots();
            this->text->clear();
            this->fileName = "无标题-记事本";
            this->setWindowTitle(this->fileName);
        }
        else if(ret == QMessageBox::No)
        {
            qDebug()<<"不保存";
            this->text->clear();
            this->fileName = "无标题-记事本";
            this->setWindowTitle(this->fileName);
        }
    }
    else//若没有修改,则直接清空文本,设置窗口标题
    {
        this->text->clear();
        this->fileName = "无标题-记事本";
        this->setWindowTitle(this->fileName);
    }
}

void MainWindow::openActionSlots()
{
    bool res = this->text->document()->isModified();
    //打开新文件,要先判断当前文档是否修改过
    if(res == true)//文档是修改过,看是否要保存
    {
        int ret = QMessageBox::question(this,"记事本","是否对修改进行保存",
                              QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
        if(ret == QMessageBox::Yes)//保存
        {
            qDebug()<<"保存";
            this->saveActionSlots();
            this->openFile();
        }
        else if(ret == QMessageBox::No)//不保存
        {
            qDebug()<<"不保存";
            this->openFile();
        }
    }
    else//文档没有修改过
    {
       this->openFile();
    }

}

void MainWindow::saveActionSlots()
{
    if(this->fileName == "无标题-记事本")
    {
        //新建一个无标题的文件,保存的话为另存为的操作,因为要给这个新文件一个位置
        this->saveasActionSlots();
    }
    else
    {
        QFile file(this->filePath);
        bool res = file.open(QFile::WriteOnly);//打开
        if(res)
        {
            //获取文本框的内容
            QString data = this->text->toPlainText();
            //写入文件中
            file.write(data.toUtf8());//把QString 转化为 QByteArray类型
            file.close();//文件关闭
            //获取文件名、设置给窗口标题
            this->fileName = QFileInfo(this->filePath).fileName();//根据文件的绝对路径,拿到文件名
            this->setWindowTitle(this->fileName);
            //把文本框的文档的修改状态改为未修改,只要保存了,就不能提示是否要保存
            this->text->document()->setModified(false);
        }
    }

}

void MainWindow::saveasActionSlots()
{
    this->filePath = QFileDialog::getSaveFileName(this,"另存为","./","TXT(*.txt)");
    //另存为,与保存类似
    QFile file(this->filePath);
    bool res = file.open(QFile::WriteOnly);//打开
    if(res)
    {
        //获取文本框的内容
        QString data = this->text->toPlainText();
        //写入文件中
        file.write(data.toUtf8());//把QString 转化为 QByteArray类型
        file.close();//文件关闭
        //获取文件名、设置给窗口标题
        this->fileName = QFileInfo(this->filePath).fileName();//根据文件的绝对路径,拿到文件名
        this->setWindowTitle(this->fileName);
        //把文本框的文档的修改状态改为未修改,只要保存了,就不能提示是否要保存
        this->text->document()->setModified(false);
    }
}

void MainWindow::copyActionSlots()
{
    this->text->copy();
}

void MainWindow::pasteActionSlots()
{
    this->text->paste();
}

void MainWindow::cutActionSlots()
{
    this->text->cut();
}

void MainWindow::undoActionSlots()
{
    this->text->undo();
}

void MainWindow::redoActionSlots()
{
    this->text->redo();
}
相关推荐
云空3 分钟前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
青莳吖14 分钟前
Java通过Map实现与SQL中的group by相同的逻辑
java·开发语言·sql
Buleall21 分钟前
期末考学C
java·开发语言
重生之绝世牛码23 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
小蜗牛慢慢爬行29 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
Algorithm157639 分钟前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
shinelord明1 小时前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
Monly211 小时前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
boligongzhu1 小时前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee20211 小时前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频