yafeilinux 发表于 2017-3-10 22:34:43

第7篇 Qt5基础(七)实现Qt文本查找功能

实现Qt文本查找功能 版权声明该文章原创于Qt开源社区(www.qter.org),作者yafeilinux,转载请注明出处!
导语
这一篇我们来添加查找菜单的功能。因为本篇还会涉及Qt Creator很多实用功能,所以单独用一篇文章来介绍。以前都用设计器设计界面,而这次我们用代码实现一个简单的查找对话框。除了讲解怎么实现查找功能,还会详细介绍怎么进行类中方法的查找和使用,以及Qt Creator程序中怎样在函数的声明和定义间进行快速切换等内容。
环境:Windows 7 + Qt 5.8.0(包含QtCreator 4.2.1)
目录一、添加查找对话框二、实现查找功能
正文
一、添加查找对话框
1.继续在前一篇程序的基础之上进行更改。首先到mainwindow.h文件中添加类的前置声明(对于什么是前置声明,以及这样使用的好处,可以自己百度一下):
class QLineEdit;class QDialog;
    注意前置声明所在的位置跟头文件包含的位置相同。
然后在private部分添加对象定义:
QLineEdit *findLineEdit;QDialog *findDlg;
下面再添加一个私有槽声明:
private slots:    void showFindText();
2.下面到mainwindow.cpp文件中,因为前面在头文件中使用了类的前置声明,所以这里需要先添加头文件包含:
#include <QDialog>
    注意QLineEdit类的头文件以前已经包含过了,所以这次只包含QDialog的头文件。然后在构造函数中进行初始化操作,即添加如下代码:
findDlg = new QDialog(this);findDlg->setWindowTitle(tr("查找"));findLineEdit = new QLineEdit(findDlg);QPushButton *btn= new QPushButton(tr("查找下一个"), findDlg);QVBoxLayout *layout= new QVBoxLayout(findDlg);layout->addWidget(findLineEdit);layout->addWidget(btn);connect(btn, &QPushButton::clicked, this, &MainWindow::showFindText);
这里创建了一个对话框,然后将一个行编辑器和一个按钮放到了上面,并使用布局管理器进行布局。最后将按钮的单击信号关联到了自定义的显示查找结果槽上。下面来添加该槽的定义。
3.这里先说一个可以快速从头文件声明处创建函数定义的方法。到mainwindow.h文件中,将鼠标定位到showFindText()函数上,然后点击右键,在弹出的菜单中选择“Refactor→在mainwindow.cpp添加定义”,如下图所示,或者直接使用Alt+Enter快捷键,这样就会直接在mainwindow.cpp文件中添加函数定义,并跳转到该函数处。

二、实现查找功能
下面我们分步完成showFindText()函数。在讲解过程中会介绍一些很实用的功能。
1.先在函数中添加一行代码来获取行编辑器中要查找的字符串。
void MainWindow::showFindText(){   QString str = findLineEdit->text();}
2.在下一行,我们先输入ui,然后按下键盘上的“>.”键,这时就会自动输入“.”或者“->”,并且列出ui上所有可用部件的对象名。如下图所示。

3.我们要输入textEdit,先输入t,这时会自动弹出textEdit,只需按下回车键即可。如下图所示。

4.下面将光标放到textEdit上,这时就会出现QTextEdit类的简单介绍,如下图所示。

5.按照提示,按下键盘上的F1键,就会在编辑器的右侧打开QTextEdit类的帮助文档。如下图所示。这时还可以按下上面的“Open in Help Mode”进入到帮助模式中打开该文档。

6.我们在该类的Public Functions公共函数列表中发现有一个find()函数。如下图所示。

7.从字面意思上可以知道该函数应该是用于查找功能的,它有两种重载形式,我们单击第一个find函数进入到它的详细介绍处。如下图所示。

8.根据介绍可以知道该函数用于查询指定的exp字符串,如果找到了就将光标跳转到查找到的位置,如果没有找到就返回false。这个函数还有一个QTextDocument::FindFlags参数,为了了解该参数的意思,我们点击该参数进入其详细介绍处。如下图所示。

可以看到该参数是一个枚举变量,用来指定查找的方式,分别是向后查找、区分大小写、全词匹配等。如果不指定该参数,默认的是向前查找、不区分大小写、包含该字符串的词也可以查找到。这几个方式还可以使用“|”符号来一起使用。
9.根据帮助,我们补充完该行代码:
ui->textEdit->find(str, QTextDocument::FindBackward);
10. 这时已经能实现查找的功能了。但是刚才看到find的返回值类型是bool型,而且,我们也应该为查找不到字符串作出提示。将这行代码更改为:
if (!ui->textEdit->find(str, QTextDocument::FindBackward)){   QMessageBox::warning(this, tr("查找"),            tr("找不到%1").arg(str));}
    这里的%1作为占位符,在显示时会被arg()中的参数替换掉,这是一种常用的在字符串中添加变量值的方式。现在查找函数的功能就基本实现了。
11. 我们会发现随着程序功能的增强,其中的函数也会越来越多,大家都会为查找某个函数的定义位置感到头疼。而在QtCreator中有几种快速定位函数的方法。
第一种,在函数声明的地方直接跳转到函数定义的地方。
例如我们在mainwindow.h文件的loadFile()函数上右击,在弹出的菜单上选择“Switch Between Function Declaration/Definition”,这时就会自动跳转到mainwindow.cpp文件中该函数的定义处。如下图所示。当然还可以反向使用。

第二种,快速查看一个文件里的所有函数。
可以在编辑器正上方的下拉框里查看正在编辑的文件中所有的函数的列表,单击一个函数就会跳转到指定位置。如下图所示。

第三种,使用类视图或者大纲视图。
在项目列表上面的下拉框中可以更改查看的内容,如果选择为类视图或者大纲,则会显示文件中所有的函数的列表。如下图所示。

第四种,使用查找功能查看函数的所有调用处。
在一个函数名上右击,然后选择“Find Usages”菜单,这时就会在下面的搜索结果栏中显示该函数所有的使用位置。我们可以通过点击一个位置来跳转到该位置。如下图所示。

第五种,使用定位器。
    有的同学可能早就发现QtCreator左下方的搜索栏了,就是上面写着“Type to locate”的搜索栏,其实我们可以把它叫做定位器,因为使用它可以很方便地定位到一个文件、帮助文档或者函数等等你需要快速定位的内容。我们按下快捷键Ctrl+K,这时会显示出多个过滤器介绍及其功能前缀,如下图所示。

    使用定位器的格式就是“过滤器前缀+空格+要定位的内容”,比如这里定位当前打开文档中的closeEvent函数,那么可以输入“m closeE”来定位,如下图所示。

12.最后,我们来实现界面上的查找功能。从设计模式进入查找动作的触发信号的槽,更改如下:
void MainWindow::on_action_Find_triggered(){   findDlg->show();}
这时运行程序,效果如下图所示。

结语
讲到这里,我们已经详细地讲解了怎样去使用一个类里面未接触过的函数;也讲解了Qt Creator中的一些便捷操作。可以看到,Qt Creator开发环境有很多很人性化的设计,大家应该熟练掌握这些操作,这样可以节省大量时间。在以后的文章中,我们不会再详细地去用帮助来说明一个函数是怎么来的,该怎么用,这些应该自己试着去查找。

源码下载:

返回主目录


HotshotBB 发表于 2017-4-27 10:06:50

一.添加查找对话框
   2.   第二部应该是#include <QLineEdit> , QDialog是之前包涵过的。

黑金队长 发表于 2017-5-1 17:36:50

connect(btn, &QPushButton::clicked(), this, &MainWindow::showFindText());

Qt5中应当去掉这两个括号

kite 发表于 2017-10-18 16:28:54

正在学习中,谢谢楼主的分享

Hstar 发表于 2017-10-18 18:44:40

谢谢楼主的分享{:3_46:}{:3_46:}

大白菜 发表于 2017-10-24 16:37:58

@yafeilinux 大神,为什么在这里不使用Q_OBJECT了呢?:dizzy:还有class QLineEdit;前置声明会编译出错:'(。

yafeilinux 发表于 2017-11-5 19:39:33

大白菜 发表于 2017-10-24 16:37
@yafeilinux 大神,为什么在这里不使用Q_OBJECT了呢?还有class QLineEdit;前置声明会编译出错。 ...

不使用Q_OBJECT了呢?
什么意思?可以下载源码测试下。

ELVE 发表于 2018-1-23 11:08:46

QT5.8 64位编译错误

在qt5.8 64位中,调试不通过,代码和楼主一样,请问如何解决

yafeilinux 发表于 2018-1-26 21:55:00

ELVE 发表于 2018-1-23 11:08
在qt5.8 64位中,调试不通过,代码和楼主一样,请问如何解决

QDiaLog中L是否大写了

猿来在这 发表于 2018-9-13 14:36:53

直接按Ctrl,左击鼠标到定义位置更方便

追梦者 发表于 2018-9-29 15:16:43

这些讲解软件操作技巧的内容放到更前面会不会更好一点?

skull 发表于 2019-6-14 13:01:38

按照教程运行后查找结果失效,查找功能失败,下载源码运行结果也是一样

yafeilinux 发表于 2019-6-14 18:50:59

skull 发表于 2019-6-14 13:01
按照教程运行后查找结果失效,查找功能失败,下载源码运行结果也是一样

你调试输出一下,看相关函数有没有执行,执行返回结果是什么

咻咻123 发表于 2019-7-17 11:18:01

有没有办法循环查找,这个总是查完一遍之后就开始报错了

xiaotongwangluo 发表于 2020-1-7 11:27:34

正在学习,想看看这个和查找数据库的区别!!!!!!!!!!!!!!
页: [1]
查看完整版本: 第7篇 Qt5基础(七)实现Qt文本查找功能