如何用Qt设计一个多文档文本编辑器

发布于:2022-12-26 ⋅ 阅读:(668) ⋅ 点赞:(0)


前言

学习了有关Qt的基础知识,下面来做一个简单的案例---多文档文本编辑器,具有新建、打开、保存一个文件、设置字体、设置字号、文字的剪切、复制、粘贴、加粗、倾斜、下划线、设置字体颜色、左对齐、居中、右对齐、撤销、重做等功能。

一、设计目标

设计一个文本编辑器首先需要在ui界面设计一个界面,里面包含许多MainWindow类的对象,可以选择给对象添加一些图标来增加美观,设计界面后在MainWindow类的头文件声明所需要的类,在源文件MainWindow.cpp中通过信号与槽来实现相应的功能。

二、效果展示

三、设计过程

1.设计思路

1.1文件的打开和新建

新建文件的本质是打开一个新窗口然后保存,新建子窗口使用MainWindow类,打开文件需要先获取文件的路径,通过readAll函数可以将文件内容都给读出来,然后再在窗口中编辑。保存文件的原理也类似,读取文件后使用QByteAarry类型的值储存接收,需要注意的是QFile类不支持utf8编码,需要自己转换。

1.2设置字体和字号

需要用到QFontComboBox和QComboBox类,这里也是本次案例的一个难点,用了设置字体的筛选器setFontFilters(可缩放字体),还用了foreach循环,语法为:foreach(变量,容器)+语句。在connect函数中需要用到QTextCharFormat类获取字符的格式,再通过mergeFormat函数转换。

1.3设置字型和颜色

也是需要用到QTextCharFormat类获取字符的格式,不过比上面简单得多,只需要获取->变化即可,这里有个注意的点,点完对象字体变粗后再点一次取消,需要用到最后一句代码。颜色方面不同的是需要新建一个系统自带的颜色窗口。

1.4设置文字对齐撤销等

其他这些就简单了,只需要调用相应的函数即可,不理解的可以去帮助文档里查看。

2.核心代码

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    resize(950,650);

    Boldcheck = true;
    Italiccheck=true;
    UnderLinecheck=true;

    //新建一个新窗口
    connect(ui->actionnew,&QAction::triggered,[=](){
       MainWindow*newWindow=new MainWindow;
       newWindow->show();
    });

    //打开一个文件
    connect(ui->actionopen,&QAction::triggered,[=](){
        //获取打开文件的路径
        QString path = QFileDialog::getOpenFileName(this,"open","../");
        QFile file(path);
        file.open(QIODevice::ReadOnly);
        QString array = file.readAll();
        ui->textEdit->setText(array);
    });

    //修改并且保存文件
    connect(ui->actionsave,&QAction::triggered,[=](){
        QString filename=QFileDialog::getSaveFileName(this,"save","E:/file.txt","*.txt");
        QFile file(filename);
        file.open(QIODevice::WriteOnly);
        QString text=ui->textEdit->toPlainText();
        //QFile默认支持的是utf8格式(Unicode编码的一种)
        file.write(text.toUtf8());
        file.close();
    });

    //设置字体字号
    fontlabel1 = new QLabel(" 字体: ");
    fontlabel2 = new QLabel(" 字号: ");
    fontComboBox = new QFontComboBox;
    fontComboBox->setFontFilters(QFontComboBox::ScalableFonts);

    sizeComboBox = new QComboBox;
    //该宏用于实现Qt的foreach循环(类似for)
    foreach(int size,dbase.standardSizes())
        sizeComboBox->addItem(QString::number(size));
    
    ui->toolBar->addWidget(fontlabel1);
    ui->toolBar->addWidget(fontComboBox);
    ui->toolBar->addWidget(fontlabel2);
    ui->toolBar->addWidget(sizeComboBox);
    ui->toolBar->addSeparator();
    //字体
    connect(fontComboBox,QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
            [=](const QString &text){
        QTextCharFormat fmt;
        fmt.setFontFamily(text);
        mergeFormat(fmt);
    });
    //字号
    connect(sizeComboBox,QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
            [=](const QString &text){
        QTextCharFormat fmt;
        fmt.setFontPointSize(text.toFloat());
        ui->textEdit->mergeCurrentCharFormat(fmt);
    });
    //粗体
    connect(ui->actionbold,&QAction::triggered,[=](){
        QTextCharFormat fmt;
        fmt=ui->textEdit->currentCharFormat();
        if(Boldcheck)
            fmt.setFontWeight(QFont::Bold);
        else
            fmt.setFontWeight(QFont::Normal);
        ui->textEdit->mergeCurrentCharFormat(fmt);
        Boldcheck=!Boldcheck;
    });
    //斜体
    connect(ui->actionitalec,&QAction::triggered,[=](){
        QTextCharFormat fmt;
        fmt=ui->textEdit->currentCharFormat();
        fmt.setFontItalic(Italiccheck);
        ui->textEdit->mergeCurrentCharFormat(fmt);
        Italiccheck=!Italiccheck;
    });
    //下划线
    connect(ui->actionunderline,&QAction::triggered,[=](){
        QTextCharFormat fmt;
        fmt=ui->textEdit->currentCharFormat();
        fmt.setFontUnderline(UnderLinecheck);
        ui->textEdit->mergeCurrentCharFormat(fmt);
        UnderLinecheck=!UnderLinecheck;
    });
    //颜色
    connect(ui->actioncolor,&QAction::triggered,[=](){
        QColor color = QColorDialog::getColor(Qt::red, this);
        QTextCharFormat format;
        format.setForeground(color);
        ui->textEdit->mergeCurrentCharFormat(format);

    });
    //向左对齐
    connect(ui->actionleft,&QAction::triggered,[=](){
        ui->textEdit->setAlignment(Qt::AlignLeft);
    });
    //向右对齐
    connect(ui->actionright,&QAction::triggered,[=](){
        ui->textEdit->setAlignment(Qt::AlignRight);
    });
    //居中对齐
    connect(ui->actioncenter,&QAction::triggered,[=](){
        ui->textEdit->setAlignment(Qt::AlignCenter);
    });
    //剪切
    connect(ui->actioncut,&QAction::triggered,[=](){
        if(ui->textEdit){
            ui->textEdit->cut();
        }
    });
    //复制
    connect(ui->actioncopy,&QAction::triggered,[=](){
        if(ui->textEdit){
            ui->textEdit->copy();
        }
    });
    //粘贴
    connect(ui->actionpaste,&QAction::triggered,[=](){
        if(ui->textEdit){
            ui->textEdit->paste();
        }
    });
    //撤销
    connect(ui->actionundo,&QAction::triggered,[=](){
        if(ui->textEdit){
            ui->textEdit->undo();
        }
    });
    //重做
    connect(ui->actionredo,&QAction::triggered,[=](){
        if(ui->textEdit){
            ui->textEdit->redo();
        }
    });
    //快捷键
    ui->actioncopy->setShortcut(tr("Ctrl+C"));
    ui->actionpaste->setShortcut(tr("Ctrl+V"));
    ui->actioncut->setShortcut(tr("Ctrl+X"));
    ui->actionundo->setShortcut(tr("Ctrl+Z"));

    //状态栏
    QLabel *textInfo= new QLabel();
    textInfo->setText("Ready");
    statusBar()->addPermanentWidget(textInfo);

}

void MainWindow::mergeFormat(QTextCharFormat format){
    QTextCursor curcor = ui->textEdit->textCursor();
    if(!curcor.hasSelection())
        curcor.select(QTextCursor::WordUnderCursor);
    curcor.mergeCharFormat(format);
    ui->textEdit->mergeCurrentCharFormat(format);
}

上述代码只供参考,因为配置环境和ui界面不一样的原因,运行一起效果可能会不一样,总之最重要的还是需要自己思考和理解。

本文含有隐藏内容,请 开通VIP 后查看