一 界面设计
1.1 新建项目
- 建立mianwindow
1.2 添加action
- 知识点:添加次级菜单的方式,直接拖拽到例如”字体“后面的到三角位置即可
1.3 界面部件
- 添加语句
ui->mdiArea->setBackground(Qt::white);
使得背景变成白色
- 添加语句
RC_ICONS += images/wps.ico
, 设置窗口图标
1.4 创建新的c++类,继承QTextEdit来实现多窗口的编辑界面显示
- 新建成的c++类如下,需要做头文件声明
#include QTextEdit
,添加Q_OBJECT
,并使其构造函数修改成TextEdit(QWidget *parent = nullptr);
,为为什么要这么做,是因为当前类继承于QTextEdit
,c++类在实现的时候,是先调用并构造父类才构造子类,而父类的构造函数里面需要传入参数QWidget *parent = nullptr
,此处不需要使用到const string,所以使用第二个构造函数,所以需要对当前的类的构造函数进行修改
二 代码实现
2.0 几个重要的连接
- 连接1:有些按键的功能需要选中文本之后才可以使用,如何判断文本是否被选中,
on_initTextAction
是自定义信号槽,将copyAvailable
中的信号发送给信号槽,控制按键是否可以使用
//如果打开的窗体中选中或取消选中文本时候,&TextEdit::copyAvailable 可以发送信号,connect(edit,&myTextEdit::copyAvailable, this, &MainWindow::on_initTextAction);void MainWindow::on_initTextAction(bool checked)
{ui->actionCut->setEnabled(checked);ui->actionCopy->setEnabled(checked);ui->actionPaste->setEnabled(checked);ui->actionColor->setEnabled(checked);ui->actionBold->setEnabled(checked);ui->actionItaly->setEnabled(checked);ui->actionUnderline->setEnabled(checked);ui->actionLeftAlign->setEnabled(checked);ui->actionRightAlign->setEnabled(checked);ui->actionCenter->setEnabled(checked);
}
- 连接2:判断子窗体是否被激活,如果被激活,启动某些按钮
//窗体被激活的时候,发出信号&QMdiArea::subWindowActivated,当前窗体的initWindowAction会收到信号//窗体被关闭也会发出信号,信号参数为0connect(ui->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::initAllWindowAction);void MainWindow::initAllWindowAction()
{bool hasACtiveWindow = (getActiveWindow() !=nullptr);ui->actionSave->setEnabled(hasACtiveWindow);ui->actionPrint->setEnabled(hasACtiveWindow);ui->actionRedo->setEnabled(hasACtiveWindow);ui->actionUndo->setEnabled(hasACtiveWindow);ui->actionNext->setEnabled(hasACtiveWindow);ui->actionPre->setEnabled(hasACtiveWindow);ui->actionPrintView->setEnabled(hasACtiveWindow);ui->actionCut->setEnabled(hasACtiveWindow);ui->actionCopy->setEnabled(hasACtiveWindow);ui->actionPaste->setEnabled(hasACtiveWindow);ui->actionColor->setEnabled(hasACtiveWindow);ui->actionBold->setEnabled(hasACtiveWindow);ui->actionItaly->setEnabled(hasACtiveWindow);ui->actionUnderline->setEnabled(hasACtiveWindow);ui->actionLeftAlign->setEnabled(hasACtiveWindow);ui->actionRightAlign->setEnabled(hasACtiveWindow);ui->actionCenter->setEnabled(hasACtiveWindow);
}
- 连接三:目的,在“窗口”菜单栏中显示所有打开的窗口
//将活动窗口添加到菜单栏actionGroup = new QActionGroup(this); //创建一个action group来装actionactionGroup->setExclusive(true); //选中的action只能有一个signalMap = new QSignalMapper(this);connect(ui->menuWindow,&QMenu::aboutToShow, this, &MainWindow::on_addActionWindowToMenu);connect(signalMap,SIGNAL(mapped(QWidget*)),this,SLOT(on_connectActionAndMap(QWidget*)));
2.1 setWindowModified
机制,作用是如果当窗显示的文档有未保存的更改,就会显示*
void TextEdit::initNewDoc()
{//修改子窗体的标题docName = QString ("文档 %1").arg(docNo++);//使用windowModified 机制,添加[*]占位符//当窗显示的文档有未保存的更改,就会显示*setWindowTitle(docName + "[*]");//document() 返回当前textEdit内的文档connect(document(),&QTextDocument::contentsChanged,this, &TextEdit::setWindowModify);
}void TextEdit::setWindowModify()
{//返回文档是否被用户修改setWindowModified(document()->isModified());
}
2.2 打印和打印预览功能,需要修改.pro文件
,包含头文件
#include <QPrinter>
#include <QPrintDialog>#include <QPrintPreviewDialog>
2.3 映射器的作用,实现多个不同的信号,捆绑连接到同一个槽函数,简化信号连接过程,但是要求是同类型的信号,映射器在当前案例中的实现就是,每个打开的文档,为其创建了一个action,将他们添加到工具栏里面显示
- action发送信号给映射器,映射器发送信号给主窗体来控制对应的子窗体,为啥不都在void MainWindow::addAcrtionsToMenu()里面connect,要去初始化函数里面连接? 是因为槽不是只调用一次
void MainWindow::init()
{。。。。。。。。connect(ui->menu_window,&QMenu::aboutToShow, this,&MainWindow::addAcrtionsToMenu);connect(signalMap,SIGNAL(mapped(QWidget*)),this,SLOT(connectActionAndMap(QWidget*)));
}void MainWindow::addAcrtionsToMenu()
{QList <QMdiSubWindow *> subWindowList = ui->mdiArea->subWindowList(); //获取子窗体列表if(!subWindowList.isEmpty()) ui->menu_window->addSeparator(); //在菜单上添加一个分隔符for(int i=0;i <subWindowList.count(); i++){QMdiSubWindow *subWindow = subWindowList[i];TextEdit *edit = qobject_cast<TextEdit*>(subWindow->widget());QString actionTitle = QString("%1 %2").arg(i+1).arg(edit->getDocName());QAction *action = ui->menu_window->addAction(actionTitle); //向菜单添加actiOnactionGroup->addAction(action);if(edit == SubWindow()) action->setCheckable(true); //对应的活动子窗体设置为被选中状态//将action 的triggered信号发送给信号映射器signalMap,由map来进行统一的转发connect(action,SIGNAL(triggered(bool)),signalMap,SLOT(map()));signalMap->setMapping(action,subWindow); //添加映射,设置信号发送者和要发送的参数}
}void MainWindow::connectActionAndMap(QWidget *widget)
{if(widget) ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(widget));
}
2.4 窗体的关闭,需要重写父类函数 void closeEvent(QCloseEvent *event) override;
,当前案例对应mainWindow有自己的关闭,以及打开的文档有自己的关闭需求,因此在各自的头文件里面都需要重写该函数,this->close()
,本质也是调用该函数
2.5 MDI添加滚动条
ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
2.6 修改MDI背景色
//背景初始化ui->mdiArea->setBackground(Qt::white);
2.7 将文本内容写入本地文件,当前案例是继承QTextEdit
,如果是继承QPlainTextEdit
,代码也不需要修改,因为 QPlainTextEdit 和 QTextEdit 都使用 QTextDocument 作为其文档模型,QTextEdit
可以处理纯文本或者富文本(除了纯文本就是富文本,包含图片或者其他HTML格式等),QPlainTextEdit
只能处理纯文本
//打开文件对话框QString filename = QFileDialog::getSaveFileName(this,"另存为","../","HTML文档(*.html);;文本文档(*.txt)");if(filename.isEmpty()){return false;}QTextDocumentWriter QdocWrite(filename);QdocWrite.write(this->document());
2.8 字号下拉框的初始化,需要手动初始化,才会产生下拉框,字体下拉框不需要手动初始化,标准格式初始化是直接在编辑组合框
里面进行内容的添加
- 初始化字体下选框,在自定义函数中实现
void MainWindow::initFontSize()
{ui->comboBoxSize->clear();for(int fontSzie:QFontDatabase::standardSizes()){ui->comboBoxSize->addItem(QString::number(fontSzie));}QFont appFont = QApplication::font(); //当前程序的默认字体int fontsize = appFont.pointSize(); // 当前应用程序的字号int sizeIndex = ui->comboBoxSize->findText(QString::number(fontsize));ui->comboBoxSize->setCurrentIndex(sizeIndex);
};
- 将选中的内容设置为相应的字号,在槽函数中实现
void MainWindow::on_comboBoxSize_activated(const QString &arg1)
{myTextEdit *edit = getActiveWindow(); //获取活动子窗体if(edit){QTextCharFormat format;format.setFontPointSize(arg1.toInt());edit->mergeCurrentCharFormat(format);}
}
三 总代码
MainWindow .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "mytextedit.h"
#include <QCloseEvent>
#include <QActionGroup>
#include <QSignalMapper>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_actionNew_triggered();void on_actionOpen_triggered();void on_actionSave_triggered();void on_actionUndo_triggered();void on_actionRedo_triggered();void on_actionCopy_triggered();void on_actionPaste_triggered();void on_actionCut_triggered();void on_actionColor_triggered();void on_actionBold_triggered(bool checked);void on_actionItaly_triggered(bool checked);void on_actionUnderline_triggered(bool checked);void on_actionLeftAlign_triggered(bool checked);void on_actionRightAlign_triggered(bool checked);void on_actionCenter_triggered(bool checked);void on_actionPingPu_triggered();void on_actionZanKai_triggered();void on_actionPre_triggered();void on_actionNext_triggered();void on_initTextAction(bool checked);void on_comboBoxStytle_activated(int index);void on_fontComboBox_activated(const QString &arg1);void on_comboBoxSize_activated(const QString &arg1);void on_addActionWindowToMenu();void on_connectActionAndMap(QWidget *widget);
protected:void closeEvent(QCloseEvent *event) override;private:Ui::MainWindow *ui;myTextEdit *getActiveWindow();void init();void initAllWindowAction();void initTextAction(bool checked); //初始化文字操作相关的按钮void initFontSize(); //初始化字号组合框QActionGroup *actionGroup;QSignalMapper *signalMap;
};
#endif // MAINWINDOW_H
myTextEdit.h
#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QObject>
#include <QTextEdit>
#include <QCloseEvent>
class myTextEdit : public QTextEdit
{Q_OBJECT
public:myTextEdit(QWidget *parent = nullptr);~myTextEdit();void NewDoc();bool OpenDoc();bool SaveDoc();bool WriteToFile(QString docRoot); //将写的内容存入指定文档bool DocSaveAs(); //已有文件做了修改,需要保存修改int get_docIndex();void loadFile(const QString filename);QString getDocName();
protected:void closeEvent(QCloseEvent *event) override;private:static int docIndex; //打开的文档的编号QString docName;QString docRoot;
private slots:void on_isDocModified();
};#endif // MYTEXTEDIT_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QColorDialog>
#include <QMdiSubWindow>
#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(Qt::white);//添加两个滚动条ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);//窗体被激活的时候,发出信号&QMdiArea::subWindowActivated,当前窗体的initWindowAction会收到信号//窗体被关闭也会发出信号,信号参数为0connect(ui->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::initAllWindowAction);initAllWindowAction();initTextAction(false); //文件界面打开的时为空,相关文字操作也应该是不能操作的initFontSize();//将活动窗口添加到菜单栏actionGroup = new QActionGroup(this); //创建一个action group来装actionactionGroup->setExclusive(true); //选中的action只能有一个signalMap = new QSignalMapper(this);connect(ui->menuWindow,&QMenu::aboutToShow, this, &MainWindow::on_addActionWindowToMenu);connect(signalMap,SIGNAL(mapped(QWidget*)),this,SLOT(on_connectActionAndMap(QWidget*)));
}void MainWindow::initAllWindowAction()
{bool hasACtiveWindow = (getActiveWindow() !=nullptr);ui->actionSave->setEnabled(hasACtiveWindow);ui->actionPrint->setEnabled(hasACtiveWindow);ui->actionRedo->setEnabled(hasACtiveWindow);ui->actionUndo->setEnabled(hasACtiveWindow);ui->actionNext->setEnabled(hasACtiveWindow);ui->actionPre->setEnabled(hasACtiveWindow);ui->actionPrintView->setEnabled(hasACtiveWindow);ui->actionCut->setEnabled(hasACtiveWindow);ui->actionCopy->setEnabled(hasACtiveWindow);ui->actionPaste->setEnabled(hasACtiveWindow);ui->actionColor->setEnabled(hasACtiveWindow);ui->actionBold->setEnabled(hasACtiveWindow);ui->actionItaly->setEnabled(hasACtiveWindow);ui->actionUnderline->setEnabled(hasACtiveWindow);ui->actionLeftAlign->setEnabled(hasACtiveWindow);ui->actionRightAlign->setEnabled(hasACtiveWindow);ui->actionCenter->setEnabled(hasACtiveWindow);
}void MainWindow::initTextAction(bool checked)
{ui->actionCut->setEnabled(checked);ui->actionCopy->setEnabled(checked);ui->actionPaste->setEnabled(checked);ui->actionColor->setEnabled(checked);ui->actionBold->setEnabled(checked);ui->actionItaly->setEnabled(checked);ui->actionUnderline->setEnabled(checked);ui->actionLeftAlign->setEnabled(checked);ui->actionRightAlign->setEnabled(checked);ui->actionCenter->setEnabled(checked);
}void MainWindow::initFontSize()
{ui->comboBoxSize->clear();for(int fontSzie:QFontDatabase::standardSizes()){ui->comboBoxSize->addItem(QString::number(fontSzie));}QFont appFont = QApplication::font(); //当前程序的默认字体int fontsize = appFont.pointSize(); // 当前应用程序的字号int sizeIndex = ui->comboBoxSize->findText(QString::number(fontsize));ui->comboBoxSize->setCurrentIndex(sizeIndex);
};void MainWindow::on_actionNew_triggered()
{myTextEdit *edit = new myTextEdit(this);ui->mdiArea->addSubWindow(edit);edit->show();edit->NewDoc();initTextAction(false); //文件界面打开的时为空,相关文字操作也应该是不能操作的//如果打开的窗体中选中或取消选中文本时候,&TextEdit::copyAvailable 可以发送信号,connect(edit,&myTextEdit::copyAvailable, this, &MainWindow::on_initTextAction);
}void MainWindow::on_actionOpen_triggered()
{myTextEdit *edit = new myTextEdit(this);ui->mdiArea->addSubWindow(edit);edit->OpenDoc();initTextAction(false);//如果打开的窗体中选中或取消选中文本时候,&TextEdit::copyAvailable 可以发送信号,connect(edit,&myTextEdit::copyAvailable, this, &MainWindow::on_initTextAction);
}void MainWindow::on_actionSave_triggered()
{myTextEdit *edit = new myTextEdit(this);ui->mdiArea->addSubWindow(edit);edit->SaveDoc();
}void MainWindow::closeEvent(QCloseEvent *event){}myTextEdit *MainWindow::getActiveWindow()
{//返回当前活动窗口,如果没有就是空QMdiSubWindow *window = ui->mdiArea->activeSubWindow();if(window){return qobject_cast<myTextEdit*>(window->widget());}else {return nullptr;}
}void MainWindow::on_actionUndo_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->undo();}
}void MainWindow::on_actionRedo_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->redo();}
}void MainWindow::on_actionCopy_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->copy();}
}void MainWindow::on_actionPaste_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->paste();}
}void MainWindow::on_actionCut_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->cut();}
}void MainWindow::on_actionColor_triggered()
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){QColor color = QColorDialog::getColor();if (color.isValid()) {QTextCharFormat format; //为字体提供颜色选择format.setForeground(color);//设置前景色edit->mergeCurrentCharFormat(format); //设置选中文本的颜色QPixmap pixmap(16,16);pixmap.fill(color);ui->actionColor->setIcon(pixmap);}}
}void MainWindow::on_actionBold_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){auto format = edit->currentCharFormat();format.setFontWeight(checked ?QFont::Bold : QFont::Normal);edit->mergeCurrentCharFormat(format);}
}void MainWindow::on_actionItaly_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){auto format = edit->currentCharFormat();format.setFontItalic(checked);edit->mergeCurrentCharFormat(format);}
}void MainWindow::on_actionUnderline_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){auto format = edit->currentCharFormat();format.setFontUnderline(checked);edit->mergeCurrentCharFormat(format);}
}void MainWindow::on_actionLeftAlign_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->setAlignment(Qt::AlignLeft);}
}void MainWindow::on_actionRightAlign_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->setAlignment(Qt::AlignRight);}
}void MainWindow::on_actionCenter_triggered(bool checked)
{myTextEdit *edit = this->getActiveWindow(); //获取活动子窗体if(edit){edit->setAlignment(Qt::AlignCenter);}
}void MainWindow::on_actionPingPu_triggered()
{ui->mdiArea->tileSubWindows();
}void MainWindow::on_actionZanKai_triggered()
{ui->mdiArea->cascadeSubWindows();
}void MainWindow::on_actionPre_triggered()
{ui->mdiArea->activatePreviousSubWindow();
}void MainWindow::on_actionNext_triggered()
{ui->mdiArea->activateNextSubWindow();
}void MainWindow::on_initTextAction(bool checked)
{ui->actionCut->setEnabled(checked);ui->actionCopy->setEnabled(checked);ui->actionPaste->setEnabled(checked);ui->actionColor->setEnabled(checked);ui->actionBold->setEnabled(checked);ui->actionItaly->setEnabled(checked);ui->actionUnderline->setEnabled(checked);ui->actionLeftAlign->setEnabled(checked);ui->actionRightAlign->setEnabled(checked);ui->actionCenter->setEnabled(checked);
}void MainWindow::on_comboBoxStytle_activated(int index)
{myTextEdit *edit = getActiveWindow(); //获取活动子窗体if(edit){if(index == 0){ //标准格式,如果之前文本有格式,要去除原本的项目符号QTextCursor curse = edit->textCursor(); //获取当前textEdit的可见游标的副本curse.beginEditBlock(); //编辑开始QTextList *list = curse.currentList();if(list){list->remove(curse.block());QTextBlockFormat blockFormat = curse.blockFormat();blockFormat.setIndent(0); //重置段落缩进curse.setBlockFormat(blockFormat);}}QTextListFormat::Style style;switch(index){case 1:style = QTextListFormat::ListSquare;break;case 2:style = QTextListFormat::ListCircle;break;case 3:style = QTextListFormat::ListDisc;break;case 4:style = QTextListFormat::ListUpperAlpha;break;case 5:style = QTextListFormat::ListLowerAlpha;break;case 6:style = QTextListFormat::ListLowerRoman;break;default:style = QTextListFormat::ListStyleUndefined;break;}QTextCursor curse = edit->textCursor(); //获取当前textEdit的可见游标的副本curse.beginEditBlock(); //编辑开始QTextBlockFormat blockFormat = curse.blockFormat();QTextListFormat listFormat;QTextList *list = curse.currentList();if(list){listFormat = list->format();list->remove(curse.block());blockFormat.setIndent(0);curse.setBlockFormat(blockFormat);}listFormat.setStyle(style);curse.createList(listFormat);curse.endEditBlock(); //编辑结束}
}void MainWindow::on_fontComboBox_activated(const QString &arg1)
{myTextEdit *edit = getActiveWindow(); //获取活动子窗体if(edit){QTextCharFormat format;format.setFontFamily(arg1);edit->mergeCurrentCharFormat(format);}
}void MainWindow::on_comboBoxSize_activated(const QString &arg1)
{myTextEdit *edit = getActiveWindow(); //获取活动子窗体if(edit){QTextCharFormat format;format.setFontPointSize(arg1.toInt());edit->mergeCurrentCharFormat(format);}
}void MainWindow::on_addActionWindowToMenu()
{QList<QAction*> actionList = actionGroup->actions();for(QAction* action : actionList) //释放掉所有组内action{delete action;}QList <QMdiSubWindow*> subwindowList = ui->mdiArea->subWindowList(); //获取子窗体列表if(!subwindowList.isEmpty()){ui->menuWindow->addSeparator(); //在“窗口”菜单栏上添加一个分隔符}for(int i=0; i< subwindowList.count(); i++){QMdiSubWindow* subwindow = subwindowList[i];//获取当前的活动的action,添加到actionGroupmyTextEdit *edit =qobject_cast<myTextEdit*> (subwindow->widget());QString actionTitle = QString("%1 %2").arg(i+1).arg(edit->getDocName());QAction *action = ui->menuWindow->addAction(actionTitle);actionGroup->addAction(action);if(edit == getActiveWindow()){action->setCheckable(true);action->setChecked(true); //对应的活动子窗体设置为被选中状态}//将action 的triggered信号发送给信号映射器signalMap,由map来进行统一的转发connect(action,SIGNAL(triggered(bool)),signalMap,SLOT(map()));signalMap->setMapping(action,subwindow); //添加映射,设置信号发送者和要发送的参数}
}void MainWindow::on_connectActionAndMap(QWidget *widget)
{if(widget) ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(widget));
}
myTextEdit.cpp
#include "mytextedit.h"
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QTextDocumentWriter>int myTextEdit::docIndex = 1;myTextEdit::myTextEdit(QWidget *parent):QTextEdit(parent)
{docName = "";docRoot = "";
}myTextEdit::~myTextEdit()
{}void myTextEdit::NewDoc()
{
// docIndex++;
// this->setWindowTitle("文档" + QString::number(this->get_docIndex()));
// this->show();docName = QString("文档%1").arg(docIndex++);//使用windowModified 机制,添加[*]占位符//当窗显示的文档有未保存的更改,就会显示*this->setWindowTitle(docName + "[*]");//document() 返回当前textEdit内的文档connect(this->document(),&QTextDocument::contentsChanged,this, &myTextEdit::on_isDocModified);this->show();
}void myTextEdit::on_isDocModified()
{//返回文档是否被用户修改setWindowModified(document()->isModified());
}bool myTextEdit::OpenDoc()
{//打开文件对话框QString fileroot = QFileDialog::getOpenFileName(this, "打开一个文件", QDir::currentPath(),"所有文件(*.*);;源文件(*.h *.cpp);;文本文件(*.txt)");if(fileroot.isEmpty()) return false;this->show();QFileInfo info(fileroot);docName = info.fileName();docRoot = fileroot;this->setWindowTitle(docName + "[*]");connect(this->document(),&QTextDocument::contentsChanged,this, &myTextEdit::on_isDocModified);this->loadFile(fileroot);
}bool myTextEdit::SaveDoc()
{if(this->document()->isModified()){if(docRoot.isEmpty()){ //如果当前文档的路径是空,说明是新建的文档//打开文件对话框QString docRoot = QFileDialog::getSaveFileName(this,"选择保存路径","../","HTML文档(*.html);;文本文档(*.txt)");if(docRoot.isEmpty()) return false;//将内容写入txtWriteToFile(docRoot);}else{ //打开的是已有的文档,需要另存为DocSaveAs();}}
}bool myTextEdit::WriteToFile(QString docRoot)
{//QTextDocumentWriter类用于将QTextDocument内容写入本地文件QTextDocumentWriter QdocWrite(docRoot);if(QdocWrite.write(this->document())){ //如果写入成功this->docRoot = QFileInfo(docRoot).canonicalFilePath(); //获取文件的绝对路径this->document()->setModified(false);setWindowModified(false); //窗口不显示*占位符}}bool myTextEdit::DocSaveAs()
{
// this->docRoot = QFileInfo(docName).canonicalFilePath(); //获取文件的绝对路径
// QTextDocumentWriter QdocWrite(docRoot);
// QdocWrite.write(this->document());QString docRoot = QFileDialog::getSaveFileName(this,"另存为","../","HTML文档(*.html);;文本文档(*.txt)");if(docName.isEmpty()) return false;return WriteToFile(docRoot);
}int myTextEdit::get_docIndex()
{return docIndex;
}void myTextEdit::loadFile(const QString filename)
{QFile file(filename);if(file.open(QIODevice::ReadOnly )){//QTextStream stream(&file);//this->setPlainText(stream.readAll());QByteArray text = file.readAll();if(Qt::mightBeRichText(text)){ //判断是不是富文本,富文本可以存图片,样式等等,纯文本只存储文字setHtml(text); //富文本显示}else{setPlainText(text); //纯文本显示}file.close();}}QString myTextEdit::getDocName()
{return docName;
}void myTextEdit::closeEvent(QCloseEvent *event)
{if(this->document()->isModified()){auto res = QMessageBox::information(this,"提示","文件未保存,是否需要保存?",QMessageBox::Save|QMessageBox::No);if(res == QMessageBox::Save){//将内容写入txtSaveDoc();}else if(res == QMessageBox::No){this->close();}}
}