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

news2024/9/20 20:18:17

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

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

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

WPS项目目录

  • 一.创建项目
  • 二.导入资源
  • 三.ui设计
  • 四.字号选择框初始化
  • 五.滚动条初始化
  • 六.添加自定义文本类
  • 七.初始化action状态
  • 八.新建文档
  • 九.打开文件
  • 十.保存与另存为
  • 十一.打印/打印预览
  • 十二.撤销重做剪切复制粘贴
  • 十三.关闭事件/退出
  • 十四.窗体菜单实现
  • 十五.动态添加action/信号映射器
  • 十六.字体颜色加粗斜体下划线
  • 十七.文本对齐
  • 十八.段落符号
  • 十九.字体字号
  • 二十.打包
  • 二十一.发布
  • 二十二.完整代码
  • 二十三.最后

一.创建项目

在这里插入图片描述
在这里插入图片描述
用的是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,让时间见证这一切吧,继续前进!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL高阶1867-最大数量高于平均水平的订单

目录 题目 准备数据 分析数据 题目 您正在运行一个电子商务网站&#xff0c;该网站正在寻找不平衡的订单。不平衡订单的订单最大数量严格大于每个订单&#xff08;包括订单本身&#xff09;的平均数量。 订单的平均数量计算为&#xff08;订单中所有产品的总数量&#xff…

visionpro脚本

visionproToolBlock的脚本的优先级优于工具连线的优先级&#xff0c;一般是照着脚本的执行顺序进行执行对应的工具&#xff0c;最常用的是C#的高级脚本&#xff0c;C#的脚本如下分为5部分。 第一部分&#xff1a;主要是一些库的引用&#xff0c;对于有些类型不知道库的时候&…

14_Python面向对象

面向过程与面向对象 在编程范式&#xff08;programming paradigms&#xff09;中&#xff0c;面向过程&#xff08;Procedural Programming&#xff09;和面向对象&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是两种主要的编程风格。 Python是一…

【医学半监督】置信度指导遮蔽学习的半监督医学图像分割

摘要: 半监督学习(Semi-supervised learning)旨在利用少数标记数据和多数未标记数据训练出高性能模型。现有方法大多采用预测任务机制,在一致性或伪标签的约束下获得精确的分割图,但该机制通常无法克服确认偏差。针对这一问题,本文提出了一种用于半监督医学图像分割的新…

(十六)Ubuntu 20.04 下搭建PX4+MATLAB 仿真环境(HITL)

在文章&#xff08;十五&#xff09;Ubuntu 20.04 下搭建PX4MATLAB 仿真环境我们学习了如何配置仿真环境&#xff0c;在本节&#xff0c;主要进行HITL的仿真环境搭建。 根据&#xff08;十五&#xff09;Ubuntu 20.04 下搭建PX4MATLAB 仿真环境完成配置到如下界面&#xff1a;…

志邦家居CIO吴俊涛谈转型:天润融通如何赋能家居行业未来

根据国家统计局、住建部等各部门综合数据显示&#xff0c;2024年国内泛家居全渠道销售额在预计将超过4.7万亿元&#xff0c;并且在存量房需求释放与智能家居品类创新的推动下&#xff0c;预计2027年将突破5.3万亿元&#xff0c;展现出强劲的增长弹性。 然而&#xff0c;家居行…

【matlab】将程序打包为exe文件(matlab r2023a为例)

文章目录 一、安装运行时环境1.1 安装1.2 简介 二、打包三、打包文件为什么很大 一、安装运行时环境 使用 Application Compiler 来将程序打包为exe&#xff0c;相当于你使用C编译器把C语言编译成可执行程序。 在matlab菜单栏–App下面可以看到Application Compiler。 或者在…

mybatisplus逻辑删除

逻辑删除配置 mybatis-plus:global-config:db-config:logic-delete-field: deletedlogic-not-delete-value:0logic-delete-value:1 查询语句也会自动加上where isdeleted0

FedOV

3 FEDOV: ONE-SHOT FEDERATED OPEN-SET VOTING FRAMEWORK 3.1 PROBLEM STATEMENT 假设有个客户端及其本地数据集。我们的目标是在服务器的帮助下&#xff0c;在不交换原始数据的情况下&#xff0c;训练一个优秀的机器学习模型 。此外&#xff0c;每个客户端只允许与服务器进行…

Linux 删除文件不释放空间问题处理

背景&#xff1a; 服务器磁盘空间已经达到100%&#xff0c;删除存放日志路径下的文件后&#xff0c;发现空间并未释放&#xff01; 原因&#xff1a;在linux系统中&#xff0c;通过rm删除文件将会从文件系统的文件夹结构上解除链接(unlink)然后删除&#xff0c;然而假设文件是被…

基于存内计算架构的模型部署与映射优化

先进计算大赛背景&#xff1a; ‘’存内计算”架构通过消除存储与计算单元间的物理距离&#xff0c;突破传统冯诺依曼架构的限制&#xff0c;自2016年起受到广泛关注&#xff0c;被视为国产算力发展的关键技术。 ​ 在存内计算架构中&#xff0c;权重布局对提高存算单元利用率…

VBA技术资料MF198:禁用下拉拖放

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

c++ day01

格式化输入 #include <iostream> #include<iomanip> using namespace std;int main() {double num1090.123456;cout<<"num"<<num<<endl;cout<<oct<<"num"<<num<<endl;cout<<hex<<&qu…

【C#】内存的使用和释放

在 C# 中&#xff0c;内存管理主要是由 .NET 的垃圾回收器&#xff08;Garbage Collector, GC&#xff09;自动处理的。然而&#xff0c;了解如何正确地使用和释放内存对于编写高效且可靠的代码非常重要。以下是一些关键点和最佳实践&#xff1a; 1. 内存分配 托管资源&#x…

如何查询论文的SCI检索号?

一、登录Web of Science 不要自己登录&#xff0c;需要选择机构为CHINA CERNET Federation&#xff0c;否则无法查询文章。 然后转到机构&#xff0c;选择对应的大学。 更具对应文章名查询文献。 二、查询文献名

python基础知识(六)--字典遍历、公共运算符、公共方法、函数、变量分类、参数分类、拆包、引用

字典遍历方法 函数名含义keys()以列表的形式&#xff0c;返回一个字典所有的键。values()以列表的形式&#xff0c;返回一个字典所有的值。items()返回由键值组成的序列&#xff0c;主要应用于遍历字典。 公共运算符 运算符描述支持的容器类型合并字符串、列表、元组*复制字符…

linux入门到实操-9 linux文件操作命令:创建文件、复制文件或文件夹、删除和移动文件、多种查看文件的方法

教程来源&#xff1a;B站视频BV1WY4y1H7d3 3天搞定Linux&#xff0c;1天搞定Shell&#xff0c;清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料&#xff08;包含课程同版本linux系统文件等内容&#xff09;&#xff0c;供大家学习交流下载&#xff1a;…

PHP限定post提交数据的次数

PHP限定post提交数据的次数。 在PHP中&#xff0c;你可以通过记录IP地址的提交次数并在会话或数据库中存储这些信息来实现这个需求。以下是一个简单的PHP示例&#xff0c;它使用会话来跟踪IP地址的提交次数。 <?php session_start(); // 获取用户的IP地址 $ip_address $…

迁移学习+多模态融合,小白轻松发一区!创新性拉满!

多模态研究如今愈发火热&#xff0c;已成为各大顶级会议的投稿热门。今天&#xff0c;我为大家提供一个多模态的创新思路&#xff1a;迁移学习与多模态融合。 迁移学习多模态融合方向的优势 1.提升模型性能&#xff1a;综合更多维度优势&#xff0c;跨模态互补 2.快速适应新…

计算机网络 --- 初识协议

序言 上一篇文章中 &#xff08;&#x1f449;点击查看&#xff09;&#xff0c;我们简单的了解了怎么寻找目标计算机&#xff0c;需要通过交换机&#xff0c;路由器等设备跨越多个网络来不断的转发我们需要传输的数据&#xff0c;直至到达目标计算机。  那我们设备之间数据是…