linux 文件查找工具栏,Qt浅谈之五:带文件查找的文本编辑器

一、简介

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

二、运行图

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

35af12bfc71c66b3d78a90a28bc38d0d.png

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

f89574dacc69e6c14504dc0485d88394.png

三、详解

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(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所示。

2144bdb24240f22c6e3cf55a52803bac.png

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

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所示。

45fefbc3374779a24609c86beaeb1bf2.png

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

5、单文档和多文档方式

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

eae14bf5d54341e83da5a2d77dae7231.png

//单文档

//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所示。

262e6537a3c06d2a4955712ce5cfaad7.png

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

//...

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值