【qt】一个WPS项目了解qt界面设计的基本套路

发布于:2024-10-09 ⋅ 阅读:(43) ⋅ 点赞:(0)

大家好,这里是国中之林!
❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←

项目功能演示:
在这里插入图片描述

放心食用!最后有完整代码.
超级详细,期待您的一个点赞❥(^_-)

一览全局:
在这里插入图片描述

一.创建项目

在这里插入图片描述
在这里插入图片描述
用的是QMainWindow类,这个包含菜单,工具栏,状态栏.
在这里插入图片描述
在这里插入图片描述
能运行出来,就说明环境搭好了.
在这里插入图片描述

二.导入资源

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三.ui设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
应用图标的添加.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四.字号选择框初始化

在这里插入图片描述
在这里插入图片描述
获取系统可支持的字号添加到选择框中,再设置当前系统字号
在这里插入图片描述
在这里插入图片描述

五.滚动条初始化

在这里插入图片描述
滚动条就是这个,这是用的后面做完的来演示的.
在这里插入图片描述

六.添加自定义文本类

在这里插入图片描述
在这里插入图片描述
记得添加宏Q_OBJECT,还有初始化父类
在这里插入图片描述
在这里插入图片描述

七.初始化action状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

八.新建文档

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

九.打开文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十.保存与另存为

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十一.打印/打印预览

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

十二.撤销重做剪切复制粘贴

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十三.关闭事件/退出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十四.窗体菜单实现

在这里插入图片描述
在这里插入图片描述

十五.动态添加action/信号映射器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十六.字体颜色加粗斜体下划线

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

十七.文本对齐

在这里插入图片描述
在这里插入图片描述

十八.段落符号

在这里插入图片描述

void MainWindow::on_comboBoxStandard_activated(int index)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        if(index==0)
        {
            QTextCursor cursor=edit->textCursor();
            cursor.beginEditBlock();

            QTextList*list=cursor.currentList();
            if(list)
            {
                list->remove(cursor.block());
                QTextBlockFormat blockFormat=cursor.blockFormat();
                blockFormat.setIndent(0);
                cursor.setBlockFormat(blockFormat);
            }
            cursor.endEditBlock();
            return;
        }
        QTextListFormat::Style style;//描述装饰列表项符号的枚举
        switch (index)
        {
        case 1:
            style=QTextListFormat::ListDisc;
            break;
        case 2:
            style=QTextListFormat::ListCircle;
            break;
        case 3:
            style=QTextListFormat::ListSquare;
            break;
        case 4:
            style=QTextListFormat::ListDecimal;
            break;
        case 5:
            style=QTextListFormat::ListLowerAlpha;
            break;
        case 6:
            style=QTextListFormat::ListUpperAlpha;
            break;
        case 7:
            style=QTextListFormat::ListLowerRoman;
            break;
        case 8:
            style=QTextListFormat::ListUpperRoman;
            break;
        default:
            style=QTextListFormat::ListStyleUndefined;//0
            break;
        }
        QTextCursor cursor=edit->textCursor();
        cursor.beginEditBlock();
        QTextBlockFormat blockFormat=cursor.blockFormat();
        QTextListFormat listFormat;

        QTextList*list=cursor.currentList();
        if(list)
        {
            listFormat=list->format();
            list->remove(cursor.block());

            blockFormat.setIndent(0);
            cursor.setBlockFormat(blockFormat);
        }

        listFormat.setStyle(style);
        cursor.createList(listFormat);
        cursor.endEditBlock();

    }
}

十九.字体字号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二十.打包

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二十一.发布

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二十二.完整代码

main.cpp

#include "mainwindow.h"

#include <QApplication>

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

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "textedit.h"
#include <QMdiSubWindow>
#include <QPrinter>
#include <QActionGroup>
#include <QSignalMapper>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_NewAction_triggered();
    void setActionStatus(bool b);

    void on_OpenAction_triggered();

    void on_saveAction_triggered();

    void on_saveAsAction_triggered();

    void on_printAction_triggered();

    void on_printViewAction_triggered();

    void printPreview(QPrinter*printer);

    void on_undoAction_triggered();

    void on_redoAction_triggered();

    void on_cutAction_triggered();

    void on_copyAction_triggered();

    void on_pasteAction_triggered();

    void on_exitAction_triggered();

    void on_closeAction_triggered();

    void on_closeAllAction_triggered();

    void on_tileAction_triggered();

    void on_cascadeAction_triggered();

    void on_nextAction_triggered();

    void on_previousAction_triggered();

    void addSubWindowAction();

    void setActiveSubWindow(QWidget*widget);

    void on_colorAction_triggered();

    void on_blodAction_triggered();

    void on_italicAction_triggered();

    void on_underLineAction_triggered();

    void on_leftAlignAction_triggered();

    void on_centerAction_triggered();

    void on_rightAlignAction_triggered();

    void on_justifyAction_triggered();

    void on_comboBoxStandard_activated(int index);

    void on_fontComboBox_activated(const QString &arg1);

    void on_comboBoxFontSize_activated(const QString &arg1);

protected:
    void closeEvent(QCloseEvent *event)override;//重写关闭事件

private:
    Ui::MainWindow *ui;
    void init();//初始化函数
    void initFontSize();//初始化字号
    void initScrollBar();//初始化滚动条
    void initWindowAction();//初始化窗体相关的action
    void initDocAction();//初始化文本相关的action
    TextEdit* activateWindow();//获取当前活动窗口
    QMdiSubWindow * findSubWindow(const QString&docName);//获取相应文档的子窗体

    QActionGroup*actionGroup;
    QSignalMapper*mapper;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFontDatabase>
#include <QMdiSubWindow>
#include <QFileDialog>
#include <QFileInfo>
#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QCloseEvent>
#include <QColorDialog>
#include <QTextCharFormat>
#include <QTextList>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this); 
    init();
}

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

void MainWindow::init()
{
    ui->mdiArea->setBackground(QBrush(Qt::white));//用画刷设置mdi背景颜色
    initFontSize();
    initScrollBar();
    initWindowAction();
    //当窗口关闭时发送一次信号,重新设置窗口action. initWindowAction
    connect(ui->mdiArea,&QMdiArea::subWindowActivated,this,&MainWindow::initWindowAction);
    connect(ui->mdiArea,&QMdiArea::subWindowActivated,this,&MainWindow::initDocAction);
    initDocAction();

    actionGroup=new QActionGroup(this);
    actionGroup->setExclusive(true);//排他选择
    mapper=new QSignalMapper(this);
    connect(ui->menu_W,&QMenu::aboutToShow,this,&MainWindow::addSubWindowAction);
    connect(mapper,SIGNAL(mapped(QWidget*)),this,SLOT(setActiveSubWindow(QWidget*)));
}

void MainWindow::initFontSize()
{
    ui->comboBoxFontSize->clear();

    //QFontDatabase提供系统可用字体的相关信息
    for(int fontSize:QFontDatabase::standardSizes())//返回标准字体大小的列表
    {
        ui->comboBoxFontSize->addItem(QString::number(fontSize));//插入到字体选择框中
    }

    QFont appFont=QApplication::font();//当前系统默认字体
    int fontSize=appFont.pointSize(); //获取字体号
    int sizeIndex=ui->comboBoxFontSize->findText(QString::number(fontSize));
    ui->comboBoxFontSize->setCurrentIndex(sizeIndex);
}

void MainWindow::initScrollBar()
{
    //设置mdi的水平和垂直滚动条当需要的时候
    ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

void MainWindow::initWindowAction()
{
    bool hasActWindow=(activateWindow()!=nullptr);
    ui->saveAction->setEnabled(hasActWindow);
    ui->saveAsAction->setEnabled(hasActWindow);
    ui->printAction->setEnabled(hasActWindow);
    ui->printViewAction->setEnabled(hasActWindow);
    ui->undoAction->setEnabled(hasActWindow);
    ui->redoAction->setEnabled(hasActWindow);
    ui->pasteAction->setEnabled(hasActWindow);
    ui->closeAction->setEnabled(hasActWindow);
    ui->closeAllAction->setEnabled(hasActWindow);
    ui->tileAction->setEnabled(hasActWindow);
    ui->cascadeAction->setEnabled(hasActWindow);
    ui->nextAction->setEnabled(hasActWindow);
    ui->previousAction->setEnabled(hasActWindow);
}

void MainWindow::initDocAction()
{
    ui->cutAction->setEnabled(false);
    ui->copyAction->setEnabled(false);
    ui->colorAction->setEnabled(false);
    ui->blodAction->setEnabled(false);
    ui->italicAction->setEnabled(false);
    ui->underLineAction->setEnabled(false);
    ui->leftAlignAction->setEnabled(false);
    ui->centerAction->setEnabled(false);
    ui->rightAlignAction->setEnabled(false);
    ui->justifyAction->setEnabled(false);
}

TextEdit *MainWindow::activateWindow()
{
    QMdiSubWindow*window=ui->mdiArea->activeSubWindow();
    if(window)
    {
        return qobject_cast<TextEdit*>(window->widget());
    }
    return nullptr;
}

QMdiSubWindow *MainWindow::findSubWindow(const QString &docName)
{
    QString filepath=QFileInfo(docName).canonicalFilePath();//返回文件的绝对路径
    for(QMdiSubWindow*sub:ui->mdiArea->subWindowList())
    {
        TextEdit* edit=qobject_cast<TextEdit*>(sub->widget());
        if(edit->getDocFilePath()==filepath)
        {
            return sub;
        }
    }
    return nullptr;
}



void MainWindow::on_NewAction_triggered()
{
    TextEdit*edit=new TextEdit;
    ui->mdiArea->addSubWindow(edit);//edit父对象将是QMdiArea的viewport小部件
    //当文本编辑器选中或者取消选中会发出copyAvailable信号.
    connect(edit,&TextEdit::copyAvailable,this,&MainWindow::setActionStatus);
    edit->initNewDoc();
    edit->show();
}

void MainWindow::setActionStatus(bool b)
{
    ui->cutAction->setEnabled(b);
    ui->copyAction->setEnabled(b);
    ui->colorAction->setEnabled(b);
    ui->blodAction->setEnabled(b);
    ui->italicAction->setEnabled(b);
    ui->underLineAction->setEnabled(b);
    ui->leftAlignAction->setEnabled(b);
    ui->centerAction->setEnabled(b);
    ui->rightAlignAction->setEnabled(b);
    ui->justifyAction->setEnabled(b);
}

void MainWindow::on_OpenAction_triggered()
{
    QString docName=QFileDialog::getOpenFileName(this,"打开文档","./","所以文件(*.*)");
    if(!docName.isEmpty())
    {
        QMdiSubWindow*sub=findSubWindow(docName);
        if(sub)
        {
            ui->mdiArea->setActiveSubWindow(sub);
            return;
        }
        TextEdit*edit=new TextEdit;
        ui->mdiArea->addSubWindow(edit);
        connect(edit,&TextEdit::copyAvailable,this,&MainWindow::setActionStatus);
        if(edit->loadDoc(docName))
        {
            statusBar()->showMessage("文档已打开",3000);//3秒显示在状态栏
            edit->show();
        }
        else
        {
            edit->close();
        }
    }
}

void MainWindow::on_saveAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        if(edit->saveDoc())
        {
            statusBar()->showMessage("文档已保存",3000);
        }
    }
}

void MainWindow::on_saveAsAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        if(edit->saveAsDoc())
        {
            statusBar()->showMessage("文档已保存",3000);
        }
    }
}

void MainWindow::on_printAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(!edit) return;
    //QPrinter::HighResolution将printer分辨率设置为正在使用的打印机分辨率
    QPrinter printer(QPrinter::HighResolution);
    QPrintDialog dialog(&printer,this);
    if(dialog.exec()==QDialog::Accepted)
    {
        edit->print(&printer);
    }
}

void MainWindow::on_printViewAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(!edit) return;
    QPrinter printer;
    QPrintPreviewDialog preview(&printer,this);
    connect(&preview,&QPrintPreviewDialog::paintRequested,this,&MainWindow::printPreview);
    if(preview.exec()==QPrintPreviewDialog::Accepted)
    {
        edit->print(&printer);
    }
}

void MainWindow::printPreview(QPrinter*printer)
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        edit->print(printer);
    }
}

void MainWindow::on_undoAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->undo();
    }
}

void MainWindow::on_redoAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->redo();
    }
}

void MainWindow::on_cutAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->cut();
    }
}

void MainWindow::on_copyAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->copy();
    }
}

void MainWindow::on_pasteAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->paste();
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    ui->mdiArea->closeAllSubWindows();
    if(ui->mdiArea->currentSubWindow())
    {
        event->ignore();
    }
    else
    {
        event->accept();
    }
}

void MainWindow::on_exitAction_triggered()
{
    close();
}

void MainWindow::on_closeAction_triggered()
{
    ui->mdiArea->closeActiveSubWindow();
}

void MainWindow::on_closeAllAction_triggered()
{
    ui->mdiArea->closeAllSubWindows();
}

void MainWindow::on_tileAction_triggered()
{
    ui->mdiArea->tileSubWindows();
}

void MainWindow::on_cascadeAction_triggered()
{
    ui->mdiArea->cascadeSubWindows();
}

void MainWindow::on_nextAction_triggered()
{
    ui->mdiArea->activateNextSubWindow();
}

void MainWindow::on_previousAction_triggered()
{
    ui->mdiArea->activatePreviousSubWindow();
}

void MainWindow::addSubWindowAction()
{
    QList<QAction*> actionList=actionGroup->actions();
    if(!actionList.isEmpty())
    {
        for(QAction*action:actionList)
        {
            delete action;
        }
    }
    QList<QMdiSubWindow*>subWindowList=ui->mdiArea->subWindowList();//获取子窗体列表
    if(!subWindowList.isEmpty())ui->menu_W->addSeparator();//添加一个分隔符
    for(int i=0;i<subWindowList.count();i++)
    {
        QMdiSubWindow*subWindow=subWindowList[i];
        TextEdit*edit=qobject_cast<TextEdit*>(subWindow->widget());
        QString action_text=QString("%1 %2").arg(i+1).arg(edit->getDocWindowTitle());
        QAction* action=ui->menu_W->addAction(action_text);
        actionGroup->addAction(action);
        action->setCheckable(true);
        if(edit==activateWindow())action->setChecked(true);//设置选中
        connect(action,SIGNAL(triggered(bool)),mapper,SLOT(map()));
        mapper->setMapping(action,subWindow);
    }

}

void MainWindow::setActiveSubWindow(QWidget *widget)
{
    if(widget)ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(widget));
}

void MainWindow::on_colorAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QColor color;
        color=QColorDialog::getColor();
        if(!color.isValid())return ;
        QTextCharFormat format;
        format.setForeground(color);
        edit->mergeCurrentCharFormat(format);

        QPixmap pixmap(24,24);
        pixmap.fill(color);
        ui->colorAction->setIcon(pixmap);
    }
}

void MainWindow::on_blodAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        bool ischecked=ui->blodAction->isChecked();
        QTextCharFormat format;
        format.setFontWeight(ischecked?QFont::Bold:QFont::Normal);
        edit->mergeCurrentCharFormat(format);
    }
}

void MainWindow::on_italicAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;
        format.setFontItalic(ui->italicAction->isChecked());
        edit->mergeCurrentCharFormat(format);
    }
}

void MainWindow::on_underLineAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;
        format.setFontUnderline(ui->underLineAction->isChecked());
        edit->mergeCurrentCharFormat(format);
    }
}

void MainWindow::on_leftAlignAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignLeft);
    }
}

void MainWindow::on_centerAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignCenter);
    }
}

void MainWindow::on_rightAlignAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignRight);
    }
}

void MainWindow::on_justifyAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignJustify);
    }
}

void MainWindow::on_comboBoxStandard_activated(int index)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        if(index==0)
        {
            QTextCursor cursor=edit->textCursor();
            cursor.beginEditBlock();

            QTextList*list=cursor.currentList();
            if(list)
            {
                list->remove(cursor.block());
                QTextBlockFormat blockFormat=cursor.blockFormat();
                blockFormat.setIndent(0);
                cursor.setBlockFormat(blockFormat);
            }
            cursor.endEditBlock();
            return;
        }
        QTextListFormat::Style style;//描述装饰列表项符号的枚举
        switch (index)
        {
        case 1:
            style=QTextListFormat::ListDisc;
            break;
        case 2:
            style=QTextListFormat::ListCircle;
            break;
        case 3:
            style=QTextListFormat::ListSquare;
            break;
        case 4:
            style=QTextListFormat::ListDecimal;
            break;
        case 5:
            style=QTextListFormat::ListLowerAlpha;
            break;
        case 6:
            style=QTextListFormat::ListUpperAlpha;
            break;
        case 7:
            style=QTextListFormat::ListLowerRoman;
            break;
        case 8:
            style=QTextListFormat::ListUpperRoman;
            break;
        default:
            style=QTextListFormat::ListStyleUndefined;//0
            break;
        }
        QTextCursor cursor=edit->textCursor();
        cursor.beginEditBlock();
        QTextBlockFormat blockFormat=cursor.blockFormat();
        QTextListFormat listFormat;

        QTextList*list=cursor.currentList();
        if(list)
        {
            listFormat=list->format();
            list->remove(cursor.block());

            blockFormat.setIndent(0);
            cursor.setBlockFormat(blockFormat);
        }

        listFormat.setStyle(style);
        cursor.createList(listFormat);
        cursor.endEditBlock();

    }
}

void MainWindow::on_fontComboBox_activated(const QString &arg1)
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;
        format.setFontFamily(arg1);
        edit->mergeCurrentCharFormat(format);
    }
}

void MainWindow::on_comboBoxFontSize_activated(const QString &arg1)
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;
        format.setFontPointSize(arg1.toInt());
        edit->mergeCurrentCharFormat(format);
    }
}

textedit.h

#ifndef TEXTEDIT_H
#define TEXTEDIT_H
#include <QTextEdit>

class TextEdit : public QTextEdit
{
     Q_OBJECT
public:
    TextEdit(QWidget*parent=nullptr);
    ~TextEdit();

    void initNewDoc(); //初始化新建文档
    QString getDocFilePath()const;//获取文件路径
    bool loadDoc(const QString&docName);//读取文件内容
    bool saveDoc();//保存文档
    bool saveAsDoc();//另存为
    QString getDocWindowTitle()const;

protected:
    void closeEvent(QCloseEvent *event)override;//重写关闭事件

private:
    QString getDocName()const;
    void initOpenDoc(const QString&docName);//初始化打开的文档
    bool writeToDoc(const QString&docName);//写文件
    bool promptSave();//提示是否保存

private slots:
    void setWindowModality();//设置WindowModality属性

private:
    QString docWindowTitle; //文档标题
    static int docNo;//文档编号
    QString docFilePath;//文档路径
};

#endif // TEXTEDIT_H

textedit.cpp

#include "textedit.h"
#include <QFile>
#include <QFileInfo>
#include <QFileDialog>
#include <QTextDocumentWriter>
#include <QCloseEvent>
#include <QMessageBox>

int TextEdit::docNo=1;

TextEdit::TextEdit(QWidget *parent):QTextEdit(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);//关闭窗口时,释放资源
    docWindowTitle="";
    docFilePath="";//路径初始化为空可以区分是否是打开的文档
}

TextEdit::~TextEdit()
{

}

void TextEdit::initNewDoc()
{
    docWindowTitle=QString("文档 %1").arg(docNo++);

    //使用windowModified机制,添加[*]占位符
    //当窗口显示的文档未保存时,*就显示出来
    setWindowTitle(docWindowTitle + "[*]");
    //当文档内容发生改变,发出contentsChanged信号
    //document() 返回当前TextEdit文档
    connect(document(),&QTextDocument::contentsChanged,this,&TextEdit::setWindowModality);
}

QString TextEdit::getDocFilePath() const
{
    return this->docFilePath;
}

QString TextEdit::getDocName() const
{
    return QFileInfo(this->docFilePath).fileName();//获取文件名称
}

bool TextEdit::loadDoc(const QString &docName)
{
    if(!docName.isEmpty())
    {
        QFile file(docName);
        if(!file.exists())return false;//文件不存在
        if(!file.open(QFile::ReadOnly))return false;//打开文件失败
        QByteArray text=file.readAll();//读取文件内容
        if(Qt::mightBeRichText(text))//如果是富文件
        {
            setHtml(text);//富文本显示
        }
        else
        {
            setPlainText(text);//纯文本显示
        }
        initOpenDoc(docName);
    }
    return true;
}

bool TextEdit::saveDoc()
{
    if(document()->isModified())//文档是否被修改
    {
        if(!docFilePath.isEmpty())//路径是否为空
        {
            return writeToDoc(docFilePath);//写文件
        }
        else
        {
            return saveAsDoc();//另存为
        }
    }
    return false;
}

bool TextEdit::saveAsDoc()
{
    QString docName=QFileDialog::getSaveFileName(this,"另存为","./","HTML文档(*.html);;文本文件(*.txt)");
    if(docName.isEmpty())return false;
    return writeToDoc(docName);
}

QString TextEdit::getDocWindowTitle() const
{
    return this->docWindowTitle;
}

bool TextEdit::promptSave()
{
    if(!document()->isModified())
    {
        return true;
    }
    QMessageBox::StandardButton res;
    res=QMessageBox::warning(this,"提示",QString("%1已修改,是否保存?").arg(docWindowTitle),
                         QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
    if(res==QMessageBox::Yes)
    {
        return saveDoc();
    }
    else if(res==QMessageBox::No)
    {
        return true;
    }
    else if(res==QMessageBox::Cancel)
    {
        return false;
    }

}

void TextEdit::closeEvent(QCloseEvent *event)
{
    if(promptSave())
    {
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void TextEdit::initOpenDoc(const QString &docName)
{
    docFilePath=QFileInfo(docName).canonicalFilePath();
    docWindowTitle=getDocName()+" "+QString::number(docNo++);
    setWindowTitle(docWindowTitle + "[*]");
    connect(document(),&QTextDocument::contentsChanged,this,&TextEdit::setWindowModality);
}

bool TextEdit::writeToDoc(const QString &docName)
{
    //QTextDocumentWriter将QTextDocument写入文件
    QTextDocumentWriter docWriter(docName);
    if(docWriter.write(document()))
    {
        docFilePath=QFileInfo(docName).canonicalFilePath();
        document()->setModified(false);//文档未改动
        setWindowModified(false);//不显示占位符标识
    }
    return true;
}



void TextEdit::setWindowModality()
{
    setWindowModified(document()->isModified());//根据是否改动来设置是否显示*
}

二十三.最后

现在是2024年9月20日15:57:22,让时间见证这一切吧,继续前进!
在这里插入图片描述