Qt项目——文本编辑器

目录

 一、界面设计

创建步骤:

界面展示:

二、功能设计

功能函数:

判断文件是否保存函数:

加载函数:

保存函数:

槽函数:

新建文件:

打开文件:

保存文件:

文件另存为:

退出:

撤销:

剪切:

 复制:

粘贴:

全选:

状态栏:

工具栏:

换行模式:

三、程序打包

1、设置图标

2、动态链接库

3、打包

四、完整代码

五、可扩展部分

六、总结


开发环境:Qt Creator 3.3.0 Based on Qt 5.4.0

 一、界面设计

创建步骤:

新建一个桌面Qt应用的项目文件,项目名称为“TextEdit”,基类选择“QMainWindow”类:

添加资源文件:

说明:由于Qt版本较低,不支持.png文件,所以在此使用的图标文件为.ico文件。

双击 mainwindow.ui 进入设计模式,添加textEdit组件:

在mainwindow.cpp文件中编写添加菜单选项以及工具图标的代码,并与相应槽函数进行连接:

    // 菜单栏
    QMenu *FileMenu = ui->menuBar->addMenu("文件");

    QAction *NewFile = new QAction(QIcon(":/new/prefix1/icon/NewFile.ico"),"新建文件",this);    // 创建动作对象
    FileMenu->addAction(NewFile);    // 将动作添加到菜单中
    NewFile->setShortcut(Qt::CTRL|Qt::Key_N);    // 添加快捷键
    connect(NewFile,SIGNAL(triggered(bool)),this,SLOT(OnNewFile()));    // 与槽函数连接

    QAction *OpenFile = FileMenu->addAction(QIcon(":/new/prefix1/icon/OpenFile.ico"),"打开文件");
    OpenFile->setShortcut(QKeySequence("Ctrl+O"));
    connect(OpenFile,SIGNAL(triggered(bool)),this,SLOT(OnOpenFile()));

    QAction *Save = FileMenu->addAction(QIcon(":/new/prefix1/icon/SaveFile.ico"),"保存");
    Save->setShortcut(tr("Ctrl+S"));
    connect(Save,SIGNAL(triggered(bool)),this,SLOT(OnSaveFile()));

    QAction *SaveAs = FileMenu->addAction(QIcon(":/new/prefix1/icon/SaveAs.ico"),"另存为");
    SaveAs->setShortcut(tr("Ctrl+Shift+S"));
    connect(SaveAs,SIGNAL(triggered(bool)),this,SLOT(OnSaveAsFile()));

    FileMenu->addSeparator();    // 添加分隔符

    QAction *Quit = FileMenu->addAction("退出");
    connect(Quit,SIGNAL(triggered(bool)),this,SLOT(OnQuit()));

    QMenu *EditMenu = ui->menuBar->addMenu("编辑");

    QAction *Undo = EditMenu->addAction(QIcon(""),"撤销");
    Undo->setShortcut(tr("Ctrl+Z"));
    connect(Undo,SIGNAL(triggered(bool)),this,SLOT(OnUndo()));

    EditMenu->addSeparator();    // 添加分隔符

    QAction *Cut = EditMenu->addAction(QIcon(":/new/prefix1/icon/Cut.ico"),"剪切");
    Cut->setShortcut(tr("Ctrl+X"));
    connect(Cut,SIGNAL(triggered(bool)),this,SLOT(OnCut()));

    QAction *Copy = EditMenu->addAction(QIcon(":/new/prefix1/icon/Copy.ico"),"复制");
    Copy->setShortcut(tr("Ctrl+C"));
    connect(Copy,SIGNAL(triggered(bool)),this,SLOT(OnCopy()));

    QAction *Paste = EditMenu->addAction(QIcon(":/new/prefix1/icon/Paste.ico"),tr("粘贴"));
    Paste->setShortcut(tr("Ctrl+V"));
    connect(Paste,SIGNAL(triggered(bool)),this,SLOT(OnPaste()));

    EditMenu->addSeparator();

    QAction *SelectAll = EditMenu->addAction("全选");
    SelectAll->setShortcut(tr("Ctrl+A"));
    connect(SelectAll,SIGNAL(triggered(bool)),this,SLOT(OnSelectAll()));

    QMenu *ViewMenu = ui->menuBar->addMenu("查看");

    QAction *StatusBar = ViewMenu->addAction("状态栏");
    StatusBar->setCheckable(true);    // 可选状态
    StatusBar->setChecked(true);      // 初始状态为选中  
    connect(StatusBar,SIGNAL(triggered(bool)),this,SLOT(OnStatusBar(bool)));

    QAction *WordWrap = ViewMenu->addAction("自动换行");
    WordWrap->setCheckable(true);
    WordWrap->setChecked(false);
    connect(WordWrap,SIGNAL(triggered(bool)),this,SLOT(OnWordWrap(bool)));

    QAction *ToolBar = ViewMenu->addAction("工具栏");
    ToolBar->setCheckable(true);
    ToolBar->setChecked(true);
    connect(ToolBar,SIGNAL(triggered(bool)),this,SLOT(OnToolBar(bool)));

    // 工具栏
    ui->mainToolBar->addAction(NewFile);
    ui->mainToolBar->addAction(OpenFile);
    ui->mainToolBar->addAction(Save);
    ui->mainToolBar->addAction(SaveAs);
    ui->mainToolBar->addSeparator();        // 添加分隔符
    ui->mainToolBar->addAction(Cut);
    ui->mainToolBar->addAction(Copy);
    ui->mainToolBar->addAction(Paste);
    ui->mainToolBar->addSeparator();        // 添加分隔符

槽函数:

private slots:

    void OnNewFile();       // 新建文件
    void OnOpenFile();      // 打开文件
    bool OnSaveFile();      // 保存文件
    bool OnSaveAsFile();    // 另存为文件

    void OnQuit();          // 退出
    void OnUndo();          // 撤销
    void OnCut();           // 剪切
    void OnCopy();          // 复制
    void OnPaste();         // 粘贴
    void OnSelectAll();     // 全选

    void OnToolBar(bool);   // 工具栏
    void OnStatusBar(bool); // 状态栏
    void OnWordWrap(bool);  // 是否自动换行

界面展示:

主界面及工具栏:

 文件菜单:

编辑菜单: 

查看菜单:

二、功能设计

功能函数:

判断文件是否保存函数:

bool MainWindow::MaybeSave()
{
    if(!ui->textEdit->document()->isModified())
        return true;
    // 创建一个警告对话框对象,返回值为点击的按钮。
    const QMessageBox::StandardButton btn = QMessageBox::warning(this,qApp->applicationName(),"是否保存当前文件到"+cur_file+"?", QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel);
    // 判断用户点击的按钮
    switch (btn) {
    case QMessageBox::Save:
        return OnSaveFile();
        break;
    case QMessageBox::Cancel:
        return false;
    default:
        break;
    }

    return true;
}

加载函数:

void MainWindow::LoadFile(const QString &path)
{
    QFile file(path);
    // 判断文件是否打开成功
    if(!file.open(QFile::ReadOnly|QFile::Text))
    {
        QMessageBox::warning(this,qApp->applicationName(),"无法打开文件!");
        return;
    }
    // 将文件内容加载到输入框中
    QTextStream in(&file);
    ui->textEdit->setPlainText(in.readAll());
    // 保存当前文件地址
    cur_file = path;
    ui->textEdit->document()->setModified(false);
    statusBar()->showMessage("文件打开成功!",2000);
}

保存函数:

bool MainWindow::SaveFile(const QString &path)
{
    QSaveFile file(path);
    // 以只写与文本方式打开文件 
    if(file.open(QFile::WriteOnly|QFile::Text))
    {
        QTextStream out(&file);
        out<<ui->textEdit->toPlainText();
        if(!file.commit())
        {
            QMessageBox::warning(this,qApp->applicationName(),"文件保存失败!");
            return false;
        }
    }
    else
        return false;
    // 保存文件路径
    cur_file = path;
    ui->textEdit->document()->setModified(false);
    statusBar()->showMessage("文件保存成功!",2000);
    return true;
}

槽函数:

新建文件:

void MainWindow::OnNewFile()
{
    if(MaybeSave())
    {
        ui->textEdit->clear();
        cur_file = QString();
        ui->textEdit->document()->setModified(false);
        statusBar()->showMessage("新建文件成功!",2000);
    }
}

打开文件:

void MainWindow::OnOpenFile()
{
    // 判断文件是否已经保存
    if(MaybeSave())
    {
        QString fileName = QFileDialog::getOpenFileName(this);
        if(!fileName.isEmpty())
            LoadFile(fileName);
        setWindowTitle(cur_file);
    }
}

保存文件:

bool MainWindow::OnSaveFile()
{
    // 判断当前文件保存路径是否为空
    if(cur_file.isEmpty())
        return OnSaveAsFile();
    else
        return SaveFile(cur_file);
}

文件另存为:

bool MainWindow::OnSaveAsFile()
{
    QFileDialog dialog(this);
    dialog.setWindowModality(Qt::WindowModal);          // 窗口模式
    dialog.setAcceptMode(QFileDialog::AcceptSave);      // 窗口类型
    dialog.setNameFilter("text(*.txt);;所有文件(*.*)");  // 文件类型筛选器
    if(dialog.exec() != QDialog::Accepted)
        return false;
    return SaveFile(dialog.selectedFiles().first());
}

退出:

void MainWindow::OnQuit()
{
    // 判断文件是否已经保存
    if(MaybeSave())
    {
        this->close();
    }
    else
    {
        // 判断当前文件路径是否为空
        if(cur_file.isEmpty())
            OnSaveAsFile();
        else
            SaveFile(cur_file);
        this->close();
    }
}

撤销:

void MainWindow::OnUndo()
{
    // 判断文件是否有可以撤销的操作
    if(ui->textEdit->isUndoRedoEnabled())
    {
        ui->textEdit->undo();
        statusBar()->showMessage("撤销成功!",2000);
    }
}

剪切:

void MainWindow::OnCut()
{
    ui->textEdit->cut();
    statusBar()->showMessage("剪切成功!",2000);
}

 复制:

void MainWindow::OnCopy()
{
    ui->textEdit->copy();
    statusBar()->showMessage("复制成功!",2000);
}

粘贴:

void MainWindow::OnPaste()
{
    ui->textEdit->paste();
    statusBar()->showMessage("粘贴成功!",2000);
}

全选:

void MainWindow::OnSelectAll()
{
    ui->textEdit->selectAll();
}

状态栏:

void MainWindow::OnStatusBar(bool flag)
{
    // 是否显示状态栏
    if(flag)
        statusBar()->show();
    else
        statusBar()->hide();
}

工具栏:

void MainWindow::OnToolBar(bool flag)
{
    // 是否打开工具栏
    if(flag)
        ui->mainToolBar->show();
    else
        ui->mainToolBar->hide();
}

换行模式:

void MainWindow::OnWordWrap(bool flag)
{
    // 是否自动换行
    if(flag)
        ui->textEdit->setWordWrapMode(QTextOption::WordWrap);
    else
        ui->textEdit->setWordWrapMode(QTextOption::NoWrap);
}

三、程序打包

1、设置图标

        设计或下载一个图标文件,新建C++资源文件,文件配置名称以.rc为后缀:

        双击.rc文件,进入编辑模式,添加下面一段代码:

IDI_ICON1 ICON DISCARDABLE "icon/Text.ico"

        进入项目的.pro文件,添加下面一段代码:

RC_FILE += icon_config.rc

        编译并运行项目,检查图标是否设置成功

2、动态链接库

        选择Release版本进行编译:

        创建一个新文件夹,将刚编译好的TextEdit.exe文件放入新建的文件夹中:

        启动Qt终端,并跳转到.exe文件路径下:

        执行下面的命令:

windeployqt TextEdit.exe

        此时该程序打包完成,双击.exe文件可以正常执行,但.exe文件必须在该文件夹中

3、打包

        下载、安装并打开软件:

下载链接:https://pan.baidu.com/s/1d2TPSFcVyQKO2DL8bvRssA

提取码:hqyj

--来自百度网盘超级会员V6的分享

整个安装一直下一步即可。

         创建一个新脚本:

         

        设置名称版本号、发布者、官网:

        配置开始菜单:

        直接点击Next:

        选择安装包的向导语言:

        安装包配置:

        直接点击Next:

        完成后桌面上出现一个安装包软件,打包完成:

四、完整代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QString cur_file; // 当前文件路径

    bool MaybeSave(); // 判断当前文件是否已保存
    void LoadFile(const QString &path);
    bool SaveFile(const QString &path);

private slots:

    void OnNewFile();       // 新建文件
    void OnOpenFile();      // 打开文件
    bool OnSaveFile();      // 保存文件
    bool OnSaveAsFile();    // 另存为文件

    void OnQuit();          // 退出
    void OnUndo();          // 撤销
    void OnCut();           // 剪切
    void OnCopy();          // 复制
    void OnPaste();         // 粘贴
    void OnSelectAll();     // 全选

    void OnToolBar(bool);   // 工具栏
    void OnStatusBar(bool); // 状态栏
    void OnWordWrap(bool);  // 是否自动换行
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
//#include <QMetaEnum>
#include <QMenu>
#include <QFile>
#include <QToolBar>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QSaveFile>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 菜单栏
    QMenu *FileMenu = ui->menuBar->addMenu("文件");

    QAction *NewFile = new QAction(QIcon(":/new/prefix1/icon/NewFile.ico"),"新建文件",this);
    FileMenu->addAction(NewFile);
    NewFile->setShortcut(Qt::CTRL|Qt::Key_N);
    connect(NewFile,SIGNAL(triggered(bool)),this,SLOT(OnNewFile()));

    QAction *OpenFile = FileMenu->addAction(QIcon(":/new/prefix1/icon/OpenFile.ico"),"打开文件");
    OpenFile->setShortcut(QKeySequence("Ctrl+O"));
    connect(OpenFile,SIGNAL(triggered(bool)),this,SLOT(OnOpenFile()));

    QAction *Save = FileMenu->addAction(QIcon(":/new/prefix1/icon/SaveFile.ico"),"保存");
    Save->setShortcut(tr("Ctrl+S"));
    connect(Save,SIGNAL(triggered(bool)),this,SLOT(OnSaveFile()));

    QAction *SaveAs = FileMenu->addAction(QIcon(":/new/prefix1/icon/SaveAs.ico"),"另存为");
    SaveAs->setShortcut(tr("Ctrl+Shift+S"));
    connect(SaveAs,SIGNAL(triggered(bool)),this,SLOT(OnSaveAsFile()));

    FileMenu->addSeparator();

    QAction *Quit = FileMenu->addAction("退出");
    connect(Quit,SIGNAL(triggered(bool)),this,SLOT(OnQuit()));

    QMenu *EditMenu = ui->menuBar->addMenu("编辑");

    QAction *Undo = EditMenu->addAction(QIcon(""),"撤销");
    Undo->setShortcut(tr("Ctrl+Z"));
    connect(Undo,SIGNAL(triggered(bool)),this,SLOT(OnUndo()));

    EditMenu->addSeparator();

    QAction *Cut = EditMenu->addAction(QIcon(":/new/prefix1/icon/Cut.ico"),"剪切");
    Cut->setShortcut(tr("Ctrl+X"));
    connect(Cut,SIGNAL(triggered(bool)),this,SLOT(OnCut()));

    QAction *Copy = EditMenu->addAction(QIcon(":/new/prefix1/icon/Copy.ico"),"复制");
    Copy->setShortcut(tr("Ctrl+C"));
    connect(Copy,SIGNAL(triggered(bool)),this,SLOT(OnCopy()));

    QAction *Paste = EditMenu->addAction(QIcon(":/new/prefix1/icon/Paste.ico"),tr("粘贴"));
    Paste->setShortcut(tr("Ctrl+V"));
    connect(Paste,SIGNAL(triggered(bool)),this,SLOT(OnPaste()));

    EditMenu->addSeparator();

    QAction *SelectAll = EditMenu->addAction("全选");
    SelectAll->setShortcut(tr("Ctrl+A"));
    connect(SelectAll,SIGNAL(triggered(bool)),this,SLOT(OnSelectAll()));

    QMenu *ViewMenu = ui->menuBar->addMenu("查看");

    QAction *StatusBar = ViewMenu->addAction("状态栏");
    StatusBar->setCheckable(true);
    StatusBar->setChecked(true);
    connect(StatusBar,SIGNAL(triggered(bool)),this,SLOT(OnStatusBar(bool)));

    QAction *WordWrap = ViewMenu->addAction("自动换行");
    WordWrap->setCheckable(true);
    WordWrap->setChecked(false);
    connect(WordWrap,SIGNAL(triggered(bool)),this,SLOT(OnWordWrap(bool)));

    QAction *ToolBar = ViewMenu->addAction("工具栏");
    ToolBar->setCheckable(true);
    ToolBar->setChecked(true);
    connect(ToolBar,SIGNAL(triggered(bool)),this,SLOT(OnToolBar(bool)));

    // 工具栏
    ui->mainToolBar->addAction(NewFile);
    ui->mainToolBar->addAction(OpenFile);
    ui->mainToolBar->addAction(Save);
    ui->mainToolBar->addAction(SaveAs);
    ui->mainToolBar->addSeparator();        // 添加分隔符
    ui->mainToolBar->addAction(Cut);
    ui->mainToolBar->addAction(Copy);
    ui->mainToolBar->addAction(Paste);
    ui->mainToolBar->addSeparator();        // 添加分隔符
}

void MainWindow::OnNewFile()
{
    if(MaybeSave())
    {
        ui->textEdit->clear();
        cur_file = QString();
        ui->textEdit->document()->setModified(false);
        statusBar()->showMessage("新建文件成功!",2000);
    }
}

void MainWindow::OnOpenFile()
{
    if(MaybeSave())
    {
        QString fileName = QFileDialog::getOpenFileName(this);
        if(!fileName.isEmpty())
            LoadFile(fileName);
        setWindowTitle(cur_file);
    }
}

bool MainWindow::OnSaveFile()
{
    if(cur_file.isEmpty())
        return OnSaveAsFile();
    else
        return SaveFile(cur_file);
}

bool MainWindow::OnSaveAsFile()
{
    QFileDialog dialog(this);
    dialog.setWindowModality(Qt::WindowModal);          // 窗口模式
    dialog.setAcceptMode(QFileDialog::AcceptSave);      // 窗口类型
    dialog.setNameFilter("text(*.txt);;所有文件(*.*)");  // 文件类型筛选器
    if(dialog.exec() != QDialog::Accepted)
        return false;
    return SaveFile(dialog.selectedFiles().first());
}
void MainWindow::OnUndo()
{
    if(ui->textEdit->isUndoRedoEnabled())
    {
        ui->textEdit->undo();
        statusBar()->showMessage("撤销成功!",2000);
    }
}

void MainWindow::OnQuit()
{
    if(MaybeSave())
    {
        this->close();
    }
    else
    {
        if(cur_file.isEmpty())
            OnSaveAsFile();
        else
            SaveFile(cur_file);
        this->close();
    }
}

void MainWindow::OnCut()
{
    ui->textEdit->cut();
    statusBar()->showMessage("剪切成功!",2000);
}

void MainWindow::OnCopy()
{
    ui->textEdit->copy();
    statusBar()->showMessage("复制成功!",2000);
}

void MainWindow::OnPaste()
{
    ui->textEdit->paste();
    statusBar()->showMessage("粘贴成功!",2000);
}

void MainWindow::OnSelectAll()
{
    ui->textEdit->selectAll();
}

void MainWindow::OnStatusBar(bool flag)
{
    // 是否显示状态栏
    if(flag)
        statusBar()->show();
    else
        statusBar()->hide();
}

void MainWindow::OnWordWrap(bool flag)
{
    // 是否自动换行
    if(flag)
        ui->textEdit->setWordWrapMode(QTextOption::WordWrap);
    else
        ui->textEdit->setWordWrapMode(QTextOption::NoWrap);
}

void MainWindow::OnToolBar(bool flag)
{
    if(flag)
        ui->mainToolBar->show();
    else
        ui->mainToolBar->hide();
}

bool MainWindow::SaveFile(const QString &path)
{
    QSaveFile file(path);
    if(file.open(QFile::WriteOnly|QFile::Text))
    {
        QTextStream out(&file);
        out<<ui->textEdit->toPlainText();
        if(!file.commit())
        {
            QMessageBox::warning(this,qApp->applicationName(),"文件保存失败!");
            return false;
        }
    }
    else
        return false;

    cur_file = path;
    ui->textEdit->document()->setModified(false);
    statusBar()->showMessage("文件保存成功!",2000);
    return true;
}

bool MainWindow::MaybeSave()
{
    if(!ui->textEdit->document()->isModified())
        return true;
    const QMessageBox::StandardButton btn = QMessageBox::warning(this,qApp->applicationName(),"是否保存当前文件到"+cur_file+"?",
                                                                 QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel);
    switch (btn) {
    case QMessageBox::Save:
        return OnSaveFile();
        break;
    case QMessageBox::Cancel:
        return false;
    default:
        break;
    }

    return true;
}

void MainWindow::LoadFile(const QString &path)
{
    QFile file(path);
    if(!file.open(QFile::ReadOnly|QFile::Text))
    {
        QMessageBox::warning(this,qApp->applicationName(),"无法打开文件!");
        return;
    }

    QTextStream in(&file);
    ui->textEdit->setPlainText(in.readAll());

    cur_file = path;
    ui->textEdit->document()->setModified(false);
    statusBar()->showMessage("文件打开成功!",2000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

 main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

五、可扩展部分

1. 可以实现多窗口

2. 菜单更加智能:刚开始打开文件时使所有菜单选项不可用,对文本进行编辑后才可进行菜单操作

3. 可以实现窗口设置保存

4. 可以添加自定义右键菜单

5. 在状态栏中显示编辑器中光标所在的行号和列号

六、总结

        该项目是一个非常好的Qt入门项目,整体难度不大,主要在于菜单栏与工具栏的槽函数编写,是个非常不错的基础入门项目。还可以在此基础上扩展更多的功能,从而实现一个更加个性化的文本编辑器,满足更多的需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值