Qt浅谈之带文件查找的文本编辑器

来源:互联网 发布:圣火名尊盾牌进阶数据 编辑:程序博客网 时间:2024/05/22 10:27

一、简介

       QT中的QMainWindow类为用户提供了一个主窗口程序,包括一个菜单栏、多个工具栏、多个锚接部件、一个状态条以及一个中央窗体,本程序结合了代码设计布局和ui的使用,全面体现了QMainWindow窗口中所用到的功能。更主要的是解决锚接部件的神秘性,解剖它的运行过程。

二、运行图

(1)QMainWindow框架,如下图1所示。


(2)本程序运行效果图,如下图2所示。


三、详解

1、创建中心部件、菜单栏、工具栏和状态栏

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void MainWindow::createCentralWidget()  
  2. {  
  3.     textEdit = new QTextEdit(this);  
  4.     setCentralWidget(textEdit);  
  5.     //textEdit->setReadOnly(true);  
  6.     connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorChanged()));  
  7.     connect(textEdit->document(), SIGNAL(contentsChanged()), this, SLOT(slotModified()));  
  8. }  
  9. void MainWindow::createMenus()  
  10. {  
  11.     fileMenu = menuBar()->addMenu(tr("&File"));  
  12.     editMenu = menuBar()->addMenu(tr("&Edit"));  
  13.     toolMenu = menuBar()->addMenu(tr("&Tool"));  
  14.   
  15.     fileMenu->addAction(fileNewAction);  
  16.     fileMenu->addAction(fileOpenAction);  
  17.     fileMenu->addAction(fileCloseAction);  
  18.     fileMenu->addSeparator();  
  19.     fileMenu->addAction(fileSaveAction);  
  20.     fileMenu->addAction(fileSaveAsAction);  
  21.     fileMenu->addSeparator();  
  22.     fileMenu->addAction(exitAction);  
  23.   
  24.     editMenu->addAction(undoAction);  
  25.     editMenu->addAction(redoAction);  
  26.     editMenu->addSeparator();  
  27.     editMenu->addAction(cutAction);  
  28.     editMenu->addAction(copyAction);  
  29.     editMenu->addAction(pasteAction);  
  30.     editMenu->addSeparator();  
  31.     editMenu->addAction(pickAllAction);  
  32.   
  33.     toolMenu->addAction(findAction);  
  34.     toolMenu->addAction(printAction);  
  35.     toolMenu->addSeparator();  
  36.     toolMenu->addAction(aboutAction);  
  37. }  
  38. void MainWindow::createToolBars()  
  39. {  
  40.     fileTool = addToolBar("File");  
  41.     fileTool->setMovable(false);  
  42.     fileTool->setOrientation(Qt::Horizontal);  
  43.     fileTool->addAction(fileNewAction);  
  44.     fileTool->addAction(fileOpenAction);  
  45.     fileTool->addAction(fileSaveAction);  
  46.     fileTool->addAction(fileSaveAsAction);  
  47.   
  48.     editTool = addToolBar("Edit");  
  49.     editTool->setAllowedAreas(Qt::AllToolBarAreas);  
  50.     editTool->setOrientation(Qt::Horizontal);  
  51.     editTool->addAction(undoAction);  
  52.     editTool->addAction(redoAction);  
  53.     editTool->addAction(copyAction);  
  54.     editTool->addAction(cutAction);  
  55.     editTool->addAction(pasteAction);  
  56. }  
  57. void MainWindow::createStatusBar()  
  58. {  
  59.     //QStatusBar* bar = statusBar();  
  60.     //bar->setStyleSheet(QString("QStatusBar::item{border: 1px}"));  
  61.     statusBar()->showMessage(tr("Begin"));  
  62. }  
在程序交叉度比较大些,尽可能的把功能分开,做到高内聚、低耦合。

2、在菜单栏开始展示最近打开的十个历史文件

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // 多文档实现  
  2. void MainWindow::setCurrentFile(const QString &fileName)  
  3. {  
  4.     curFile = QFileInfo(fileName).canonicalFilePath();  
  5.     isUntitled = false;  
  6.     setWindowTitle(curFile + "[*]");  
  7.   
  8.     textEdit->document()->setModified(false);  
  9.     setWindowModified(false);  
  10.   
  11.     QSettings settings("710""main_example");  
  12.     QStringList files = settings.value("recentFiles").toStringList();  
  13.     files.removeAll(fileName);  
  14.     files.prepend(fileName);  
  15.     while (files.size() > MaxRecentFiles) {  
  16.         files.removeLast();  
  17.     }  
  18.     settings.setValue("recentFiles", files);  
  19.   
  20.     //updateRecentFiles();   单文档采用  
  21.     foreach (QWidget *widget, QApplication::topLevelWidgets()) {  
  22.         MainWindow *mainWindow = qobject_cast<MainWindow *>(widget);  
  23.         if (mainWindow)  mainWindow->updateRecentFiles();  
  24.     }  
  25. }  
  26. void MainWindow::updateRecentFiles()  
  27. {  
  28.     QSettings settings("710""main_example");  
  29.     QStringList files = settings.value("recentFiles").toStringList();  
  30.   
  31.     int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);  
  32.     for (int i = 0; i < numRecentFiles; ++i) {  
  33.         QString text = tr("&%1 %2").arg(i + 1).arg(files[i]);  
  34.         recentFileActs[i]->setText(text);  
  35.         recentFileActs[i]->setData(files[i]);  
  36.         recentFileActs[i]->setVisible(true);  
  37.     }  
  38.     for (int i = numRecentFiles; i < MaxRecentFiles; ++i)  
  39.         recentFileActs[i]->setVisible(false);  
  40.   
  41.     separatorAct->setVisible(numRecentFiles > 0);  
  42. }  
  43. void MainWindow::createCurFileMenu()  
  44. {  
  45.     separatorAct = fileMenu->insertSeparator(exitAction);  
  46.     separatorAct->setVisible(false);  
  47.     for (int i = 0; i < MaxRecentFiles; ++i) {  
  48.          recentFileActs[i] = new QAction(this);  
  49.          fileMenu->insertAction(separatorAct, recentFileActs[i]);  
  50.          recentFileActs[i]->setVisible(false);  
  51.          connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));  
  52.      }  
  53. }  
        利用QSettings保存最近打开的十个历史文件,并在下次程序运行是从QSettings settings("710", "main_example");中加载这个文件的绝对路径到文件菜单下,并提供triggered()的信号处理。而且每次打开一个文件及时更新该列表。

3、锚接部件

锚接部件设置,开始不浮动停靠在右侧,可以停靠在所有方位。

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void MainWindow::insertDockWidget()  
  2. {  
  3.     dockWidget = new QDockWidget(tr("find file"), this);  
  4.     findFileForm = new CFindFileForm(dockWidget);  
  5.     dockWidget->setAllowedAreas(Qt::RightDockWidgetArea);  
  6.     //dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas);  
  7.     dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);  
  8.     dockWidget->setFloating(false);  
  9.     dockWidget->setWidget(findFileForm);  
  10.     dockWidget->setVisible(true);  
  11.   
  12.     addDockWidget(Qt::RightDockWidgetArea, dockWidget);  
  13.     connect(findFileForm, SIGNAL(doCellClicked(intint)), this, SLOT(slotCellClicked(intint)));  
  14. }  
锚接部件浮在主窗口之上,如下图3所示。

对于查找文件后双击列表的文件路径所在的单元格,就能打开该文件。

4、文本编辑

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //  设置光标的选区,使格式作用于选区内的字符,若没有选区则作用于光标所在处的字符  
  2. void MainWindow::mergeFormat(QTextCharFormat fmt)  
  3. {  
  4.     QTextCursor cursor = textEdit->textCursor();  
  5.     if (!cursor.hasSelection()) {  
  6.        cursor.select(QTextCursor::WordUnderCursor);  
  7.     }  
  8.     cursor.mergeCharFormat(fmt);  
  9.     textEdit->mergeCurrentCharFormat(fmt);  
  10. }  
  11.   
  12. void MainWindow::slotFont(QString type)  
  13. {  
  14.     QTextCharFormat fmt;  
  15.     fmt.setFontFamily(type);  
  16.     mergeFormat(fmt);  
  17. }  
  18.   
  19. void MainWindow::slotSize(QString size)  
  20. {  
  21.     QTextCharFormat fmt;  
  22.     fmt.setFontPointSize(size.toFloat());  
  23.     mergeFormat(fmt);  
  24. }  
  25.   
  26. void MainWindow::slotBold()  
  27. {  
  28.     QTextCharFormat fmt;  
  29.     fmt.setFontWeight(boldToolBtn->isChecked()? QFont::Bold : QFont::Normal);  
  30.     mergeFormat(fmt);  
  31. }  
  32.   
  33. void MainWindow::slotItalic()  
  34. {  
  35.     QTextCharFormat fmt;  
  36.     fmt.setFontItalic(italicToolBtn->isChecked());  
  37.     mergeFormat(fmt);  
  38. }  
  39.   
  40. void MainWindow::slotUnder()  
  41. {  
  42.     QTextCharFormat fmt;  
  43.     fmt.setFontUnderline(underToolBtn->isChecked());  
  44.     mergeFormat(fmt);  
  45. }  
  46.   
  47. void MainWindow::slotColor()  
  48. {  
  49.     QColor color = QColorDialog::getColor(Qt::red,this);  
  50.     if(color.isValid()) {  
  51.         QTextCharFormat fmt;  
  52.         fmt.setForeground(color);  
  53.         mergeFormat(fmt);  
  54.     }  
  55. }  
  56.   
  57. void MainWindow::slotCurrentFormatChanged(const QTextCharFormat &fmt)  
  58. {  
  59.     fontComboBox->setCurrentIndex(fontComboBox->findText(fmt.fontFamily()));  
  60.     fontComboBox->setCurrentIndex(fontComboBox->findText(QString::number(fmt.fontPointSize())));  
  61.     boldToolBtn->setChecked(fmt.font().bold());  
  62.     italicToolBtn->setChecked(fmt.fontItalic());  
  63.     underToolBtn->setChecked(fmt.fontUnderline());  
  64. }  
效果图如下图4所示。

       通过QTextCharFormat类设置光标选区文字的字体、字号、加粗、倾斜、颜色、样式和对齐方式。调用了Qt内置的字体格式和颜色对话框QColorDialog::getColor(Qt::red,this);

5、单文档和多文档方式

多文档方式打开框口,如下如5所示。


[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //单文档  
  2. //void CMainWindow::doNew()  
  3. //{  
  4. //  maybeSave();  
  5. //  isUntitled = true;  
  6. //    curFile = tr("untitled");  
  7. //  setWindowTitle(curFile + "[*]");  
  8. //  textEdit->clear();  
  9. //  textEdit->setVisible(true);  
  10. //  setWindowModified(false);  
  11. //}  
  12. void MainWindow::slotNewFile()  
  13. {  
  14.     MainWindow *newWin = new MainWindow;  
  15.     newWin->show();  
  16. }  

        多文档就是打开多个独立的窗口操作,单文档是始终在一个窗口操作。注意文件关闭时的保存,还有多文档时打开菜单下历史文件名字的多窗口的更新操作。

6、文件查找

查找文件对话框是通过ui设计的,如下如6所示。

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. QStringList CFindFileForm::findFiles(const QDir &dir, const QString &fileName,  
  2.                                const QString &txt)  
  3. {  
  4.      QStringList files = dir.entryList(QStringList(fileName),  
  5.                                  QDir::Files | QDir::NoSymLinks);  
  6.     if (txt.isEmpty())  
  7.          return files;  
  8.     QStringList foundFiles;  
  9.     Qt::CaseSensitivity sensitive = Qt::CaseInsensitive;  
  10.     if(m_bSensitive)  
  11.         sensitive = Qt::CaseSensitive;  
  12.  for (int i = 0; i < files.size(); ++i)  
  13.     {  
  14.         qApp->processEvents();  
  15.         if (m_bStoped)  
  16.              break;  
  17.   
  18.         QFile file(dir.absoluteFilePath(files[i]));  
  19.         if (file.open(QIODevice::ReadOnly))  
  20.         {  
  21.             QString line;  
  22.             QTextStream in(&file);  
  23.             while (!in.atEnd())  
  24.             {  
  25.                 if (m_bStoped)  
  26.                     break;  
  27.                 line = in.readLine();  
  28.                 if (line.contains(txt, sensitive))  
  29.                 {  
  30.                     foundFiles << files[i];  
  31.                     break;  
  32.                 }  
  33.             }  
  34.         }  
  35.     }  
  36.     return foundFiles;  
  37. }  

        可以以文件名加路径查找,可以以文件包含的内容加路径查找,区分大小写和子目录的递归查找。显示查找结果,点击查找中的文件路径直接显示在左侧的中心部件中。

四、总结

(1)因本代码比较多,讲解不能面面俱全,请下载源码阅读理解。

(2)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7527461)。   

(3)本人水平有限,错误重现,请读者及时指出,若有更好的设计建议,也可发邮件联系,在此先感谢!

           邮箱地址yang.ao@i-soft.com.cn。

(4)所用的Qt的库Qt4.6.2,GCC4.4.6 20120305 (Red Hat 4.4.6-4) 。系统是centos6.3。

五、patch1

(1)当关闭中心部件时(菜单栏的关闭),再次打开文件时,文件内容不显示,修改为:增加textEdit->setVisible(true);

[cpp] view plaincopy
  1. bool MainWindow::loadFile(const QString &fileName)  
  2. {  
  3.     QFile file(fileName);  
  4.     if (!file.open(QFile::ReadOnly | QFile::Text)) {  
  5.         QMessageBox::warning(this, tr("read file"),  
  6.                             tr("can not read file %1:\n%2.")  
  7.                             .arg(fileName)  
  8.                             .arg(file.errorString()));  
  9.         return false;  
  10.     }  
  11.     textEdit->setVisible(true);  
  12.     //...  

0 0
原创粉丝点击