Qt项目——文本编辑器(功能模块②)

avatar
作者
筋斗云
阅读量:0

项目地址:GitHub - Outlier9/CatEditor: Cat文本编辑器--Qt

有帮助的话各位点点 star 啦,感谢!

如果有需要学习该项目的人,觉得看文档较为困难,可以加我联系方式,给github点个star后可免费提供学习视频!!!

(4)各种功能添加槽函数

.ui文件的各个Action选项右击选择转到槽,选择triggered信号,调用对应的方法(均已封装好,可以直接调用)

这里有新建、关闭、关闭所有、平铺、层叠、下一个、上一个

void MainWindow::on_newAction_triggered() {     docNew(); }  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::closeEvent(QCloseEvent *event) {     ui->mdiArea->closeAllSubWindows();     //防止在关闭主窗口时意外丢失未保存的数据     if(ui->mdiArea->currentSubWindow())         event->ignore();  //如果存在当前活动的子窗口,忽略关闭事件。这意味着窗口不会关闭,用户可以继续操作     else         event->accept(); //接受此事件 }

(5)打开文档

.ui界面对openAction转到槽,选triggered信号,然后和新建文档一样,我们将打开操作进行封装,命名为docOpen

加载文件的时候有可能成功也可能失败,所以这里需要一个验证

bool loadDoc(const QString& docName); //加载文档验证 void setCurDoc(const QString& docName);//设置当前文档路径及相关状态
//加载指定名称的文档 bool ChileWnd::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); //设置为纯文本          setCurDoc(docName); //设置当前文档路径         connect(document(),SIGNAL(contentsChanged()),this,SLOT(docBeModified()));          return true;     } }  //设置当前文档路径及相关状态 void ChileWnd::setCurDoc(const QString &docName) {     //返回标准名称路径,可以过滤“.”和“..”     m_CurDocPath = QFileInfo(docName).canonicalFilePath();     m_bSaved = true;                            //文档已被保存     document()->setModified(false);             //文档未被改动     setWindowModified(false);                   //窗口不显示改动标识     setWindowTitle(getCurDocName() + "[*]");    //设置子窗口标题 }
public:     void docOpen(); private: //匹配子窗口是否存在 QMdiSubWindow* findChileWnd(const QString &docName);
void MainWindow::docOpen() {     QString docName = QFileDialog::getOpenFileName(this,                                      "打开文档",                                      "",                                      "文本文件(*.txt);;"                                      "HTML文件(*.html *.htm);;"                                      "所有文件(*.*)");      //如果用户选择了文件并且文件名不为空,则继续执行     if(!docName.isEmpty())     {         //查找是否已经有窗口打开了这个文档。如果找到已经存在的窗口,则将其激活,并返回         QMdiSubWindow *existWnd = findChileWnd(docName);         if(existWnd)         {             ui->mdiArea->setActiveSubWindow(existWnd);             return;         }          //如果文档尚未被打开,创建一个新的 ChileWnd 子窗口,并将其添加到 QMdiArea 中         ChileWnd *childWnd = new ChileWnd;         ui->mdiArea->addSubWindow(childWnd);         //连接子窗口的信号和主窗口的槽         connect(childWnd,SIGNAL(copyAvailable(bool)),                 ui->cutAction,SLOT(setEnabled(bool)));         connect(childWnd,SIGNAL(copyAvailable(bool)),                 ui->copyAction,SLOT(setEnabled(bool)));          //加载文档内容         if(childWnd->loadDoc(docName))         {             //显示状态栏信息 "文档已打开" 持续 3 秒             statusBar()->showMessage("文档已打开",3000);             childWnd->show();             formatEnable();         }         else         {             //加载失败,则关闭创建的子窗口             childWnd->close();         }     } }   //匹配子窗口是否存在 QMdiSubWindow *MainWindow::findChileWnd(const QString &docName) {     //获取文件的标准路径     QString strFile = QFileInfo(docName).canonicalFilePath();     //遍历所有子窗口     foreach(QMdiSubWindow* subWnd,ui->mdiArea->subWindowList()){         //转换子窗口的 widget 为 ChileWnd         ChileWnd* childWnd = qobject_cast<ChileWnd*>(subWnd->widget());         //比较子窗口的当前文档路径         if(childWnd->m_CurDocPath == strFile)             //如果相同,表示找到了对应的子窗口,返回该子窗口指针 subWnd             return subWnd;     }     //未找到对应子窗口的情况     return 0; }

(6)保存/另存为文档

.ui界面对saveAction和saveOther转到槽,选triggered信号,然后和新建文档一样,我们将两种保存操作进行封装,命名为docSavedocSaveAs

bool saveDoc(); //保存文档 bool saveAsDoc(); //另存为 bool saveDocOpt(QString docName); //保存文件的操作逻辑
 //保存文档 bool ChileWnd::saveDoc() {     //查询文档当前是否保存的状态(全局变量)     if(m_bSaved)         return saveDocOpt(m_CurDocPath);     else         saveAsDoc(); }  //另存为 bool ChileWnd::saveAsDoc() {     QString docName = QFileDialog::getSaveFileName(this,                                  "另存为",                                  "文档.txt", // 默认保存为 txt 格式                                  "文本文件(*.txt);;"                                  "HTML文件(*.html *.htm);;"                                  "Word文件(*.doc *.docx);;"                                  "PDF文件(*.pdf);;"                                  "图片文件(*.png *.jpg *.jpeg *.bmp);;"                                  "所有文件(*.*)");     if(docName.isEmpty())         return false;     else         return saveDocOpt(docName); }  //保存文件的操作逻辑 bool ChileWnd::saveDocOpt(QString docName) {     //CaseInsensitive大小写都可以     if( !(docName.endsWith(".htm",Qt::CaseInsensitive)||                         docName.endsWith(".html",Qt::CaseInsensitive)))     {         //如果没有后缀就添加         docName += ".html";     }     创建一个 QTextDocumentWriter 对象 writer,用于写入文档     QTextDocumentWriter writer(docName);     bool isSuccess = writer.write(this->document());     //如果成功写入,就设置文档名字     if(isSuccess)     {         setCurDoc(docName);     }     return isSuccess; }
void docSave(); void docSaveAs();
//保存 void MainWindow::docSave() {     //如果该活动窗口存在且它的saveDoc返回值为true也就是保存成功     if(activateChildWnd() && activateChildWnd()->saveDoc())     {         statusBar()->showMessage("保存成功",3000);     } }  //另存为 void MainWindow::docSaveAs() {     //如果该活动窗口存在且它的saveDoc返回值为true也就是保存成功     if(activateChildWnd() && activateChildWnd()->saveAsDoc())     {         statusBar()->showMessage("保存成功",3000);     } }  //Action转到槽 void MainWindow::on_saveAction_triggered() {     docSave(); }  void MainWindow::on_saveOther_triggered() {     docSaveAs(); }

在关闭文档的时候,如果文档此时的状态是被修改且未保存,就出现一个提示并可以选择保存,在子类中实现该方法promptSave,然后添加关闭事件处理

protected:     void closeEvent(QCloseEvent *event); //关闭事件发生时,进行未保存该文档提示 private:     bool promptSave(); //提示未保存但是要关闭的时候进行保存
void ChileWnd::closeEvent(QCloseEvent *event) {     if(promptSave())         event->accept();     else         event->ignore();  }  //提示未保存但是要关闭的时候进行保存 bool ChileWnd::promptSave() {     if(!document()->isModified())         return true;     //提示消息框     QMessageBox::StandardButton result;     result = QMessageBox::warning(this,                                   QString("系统提示"),                                   QString("文档%1已修改,是否保存?")                                   .arg(getCurDocName()),                                   QMessageBox::Yes | QMessageBox::Discard | QMessageBox::Cancel);     if(result == QMessageBox::Yes)         return saveDoc();     else if(result == QMessageBox::Cancel)         return false;     return true;      if(!document()->isModified())         return true;  }

现在点击打开和保存就已经生效了 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!