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

来源:互联网 发布:自学考试网络报名 编辑:程序博客网 时间:2024/05/01 00:01

一、简介

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

二、运行图

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


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


三、详解

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

void MainWindow::createCentralWidget(){    textEdit = new QTextEdit(this);    setCentralWidget(textEdit);    //textEdit->setReadOnly(true);    connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorChanged()));    connect(textEdit->document(), SIGNAL(contentsChanged()), this, SLOT(slotModified()));}void MainWindow::createMenus(){    fileMenu = menuBar()->addMenu(tr("&File"));    editMenu = menuBar()->addMenu(tr("&Edit"));    toolMenu = menuBar()->addMenu(tr("&Tool"));    fileMenu->addAction(fileNewAction);    fileMenu->addAction(fileOpenAction);    fileMenu->addAction(fileCloseAction);    fileMenu->addSeparator();    fileMenu->addAction(fileSaveAction);    fileMenu->addAction(fileSaveAsAction);    fileMenu->addSeparator();    fileMenu->addAction(exitAction);    editMenu->addAction(undoAction);    editMenu->addAction(redoAction);    editMenu->addSeparator();    editMenu->addAction(cutAction);    editMenu->addAction(copyAction);    editMenu->addAction(pasteAction);    editMenu->addSeparator();    editMenu->addAction(pickAllAction);    toolMenu->addAction(findAction);    toolMenu->addAction(printAction);    toolMenu->addSeparator();    toolMenu->addAction(aboutAction);}void MainWindow::createToolBars(){    fileTool = addToolBar("File");    fileTool->setMovable(false);    fileTool->setOrientation(Qt::Horizontal);    fileTool->addAction(fileNewAction);    fileTool->addAction(fileOpenAction);    fileTool->addAction(fileSaveAction);    fileTool->addAction(fileSaveAsAction);    editTool = addToolBar("Edit");    editTool->setAllowedAreas(Qt::AllToolBarAreas);    editTool->setOrientation(Qt::Horizontal);    editTool->addAction(undoAction);    editTool->addAction(redoAction);    editTool->addAction(copyAction);    editTool->addAction(cutAction);    editTool->addAction(pasteAction);}void MainWindow::createStatusBar(){    //QStatusBar* bar = statusBar();    //bar->setStyleSheet(QString("QStatusBar::item{border: 1px}"));    statusBar()->showMessage(tr("Begin"));}
在程序交叉度比较大些,尽可能的把功能分开,做到高内聚、低耦合。

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

// 多文档实现void MainWindow::setCurrentFile(const QString &fileName){    curFile = QFileInfo(fileName).canonicalFilePath();    isUntitled = false;    setWindowTitle(curFile + "[*]");    textEdit->document()->setModified(false);    setWindowModified(false);    QSettings settings("710", "main_example");    QStringList files = settings.value("recentFiles").toStringList();    files.removeAll(fileName);    files.prepend(fileName);    while (files.size() > MaxRecentFiles) {        files.removeLast();    }    settings.setValue("recentFiles", files);    //updateRecentFiles();   单文档采用    foreach (QWidget *widget, QApplication::topLevelWidgets()) {        MainWindow *mainWindow = qobject_cast<MainWindow *>(widget);        if (mainWindow)  mainWindow->updateRecentFiles();    }}void MainWindow::updateRecentFiles(){    QSettings settings("710", "main_example");    QStringList files = settings.value("recentFiles").toStringList();    int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);    for (int i = 0; i < numRecentFiles; ++i) {        QString text = tr("&%1 %2").arg(i + 1).arg(files[i]);        recentFileActs[i]->setText(text);        recentFileActs[i]->setData(files[i]);        recentFileActs[i]->setVisible(true);    }    for (int i = numRecentFiles; i < MaxRecentFiles; ++i)        recentFileActs[i]->setVisible(false);    separatorAct->setVisible(numRecentFiles > 0);}void MainWindow::createCurFileMenu(){    separatorAct = fileMenu->insertSeparator(exitAction);    separatorAct->setVisible(false);    for (int i = 0; i < MaxRecentFiles; ++i) {         recentFileActs[i] = new QAction(this);         fileMenu->insertAction(separatorAct, recentFileActs[i]);         recentFileActs[i]->setVisible(false);         connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));     }}
        利用QSettings保存最近打开的十个历史文件,并在下次程序运行是从QSettings settings("710", "main_example");中加载这个文件的绝对路径到文件菜单下,并提供triggered()的信号处理。而且每次打开一个文件及时更新该列表。

3、锚接部件

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

void MainWindow::insertDockWidget(){    dockWidget = new QDockWidget(tr("find file"), this);    findFileForm = new CFindFileForm(dockWidget);    dockWidget->setAllowedAreas(Qt::RightDockWidgetArea);    //dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas);    dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);    dockWidget->setFloating(false);    dockWidget->setWidget(findFileForm);    dockWidget->setVisible(true);    addDockWidget(Qt::RightDockWidgetArea, dockWidget);    connect(findFileForm, SIGNAL(doCellClicked(int, int)), this, SLOT(slotCellClicked(int, int)));}
锚接部件浮在主窗口之上,如下图3所示。

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

4、文本编辑

//  设置光标的选区,使格式作用于选区内的字符,若没有选区则作用于光标所在处的字符void MainWindow::mergeFormat(QTextCharFormat fmt){    QTextCursor cursor = textEdit->textCursor();    if (!cursor.hasSelection()) {       cursor.select(QTextCursor::WordUnderCursor);    }    cursor.mergeCharFormat(fmt);    textEdit->mergeCurrentCharFormat(fmt);}void MainWindow::slotFont(QString type){    QTextCharFormat fmt;    fmt.setFontFamily(type);    mergeFormat(fmt);}void MainWindow::slotSize(QString size){    QTextCharFormat fmt;    fmt.setFontPointSize(size.toFloat());    mergeFormat(fmt);}void MainWindow::slotBold(){    QTextCharFormat fmt;    fmt.setFontWeight(boldToolBtn->isChecked()? QFont::Bold : QFont::Normal);    mergeFormat(fmt);}void MainWindow::slotItalic(){    QTextCharFormat fmt;    fmt.setFontItalic(italicToolBtn->isChecked());    mergeFormat(fmt);}void MainWindow::slotUnder(){    QTextCharFormat fmt;    fmt.setFontUnderline(underToolBtn->isChecked());    mergeFormat(fmt);}void MainWindow::slotColor(){    QColor color = QColorDialog::getColor(Qt::red,this);    if(color.isValid()) {        QTextCharFormat fmt;        fmt.setForeground(color);        mergeFormat(fmt);    }}void MainWindow::slotCurrentFormatChanged(const QTextCharFormat &fmt){    fontComboBox->setCurrentIndex(fontComboBox->findText(fmt.fontFamily()));    fontComboBox->setCurrentIndex(fontComboBox->findText(QString::number(fmt.fontPointSize())));    boldToolBtn->setChecked(fmt.font().bold());    italicToolBtn->setChecked(fmt.fontItalic());    underToolBtn->setChecked(fmt.fontUnderline());}
效果图如下图4所示。

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

5、单文档和多文档方式

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


//单文档//void CMainWindow::doNew()//{//maybeSave();//isUntitled = true;//    curFile = tr("untitled");//setWindowTitle(curFile + "[*]");//textEdit->clear();//textEdit->setVisible(true);//setWindowModified(false);//}void MainWindow::slotNewFile(){    MainWindow *newWin = new MainWindow;    newWin->show();}

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

6、文件查找

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

QStringList CFindFileForm::findFiles(const QDir &dir, const QString &fileName,                               const QString &txt){     QStringList files = dir.entryList(QStringList(fileName),                                 QDir::Files | QDir::NoSymLinks);    if (txt.isEmpty())         return files;    QStringList foundFiles;    Qt::CaseSensitivity sensitive = Qt::CaseInsensitive;    if(m_bSensitive)        sensitive = Qt::CaseSensitive; for (int i = 0; i < files.size(); ++i)    {        qApp->processEvents();        if (m_bStoped)             break;        QFile file(dir.absoluteFilePath(files[i]));        if (file.open(QIODevice::ReadOnly))        {            QString line;            QTextStream in(&file);            while (!in.atEnd())            {                if (m_bStoped)                    break;                line = in.readLine();                if (line.contains(txt, sensitive))                {                    foundFiles << files[i];                    break;                }            }        }    }    return foundFiles;}

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

四、总结

(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);

bool MainWindow::loadFile(const QString &fileName){    QFile file(fileName);    if (!file.open(QFile::ReadOnly | QFile::Text)) {        QMessageBox::warning(this, tr("read file"),                            tr("can not read file %1:\n%2.")                            .arg(fileName)                            .arg(file.errorString()));        return false;    }    textEdit->setVisible(true);    //...}


0 0
原创粉丝点击