Qt Creator 的查找对话框允许用户使用文本或者正则表达式进行搜索。点击“编辑-查找/替换-高级查找”即可打开查找对话框。

查找对话框:

在查找对话框中,“范围”和“文件模式”两项都是可以扩展的。也是就说,我们可以利用插件,向范围下拉框添加更多项目,每次都可以依据选择的下拉项不同,读取不同的配置文件。在 Qt Creator 中,范围下拉框中的每一项都叫做“查找过滤器(find filter)”。
Find::IFindFilter
Qt Creator 的 find 插件暴露出的接口是Find::IFindFilter,该接口在 src/plugins/find/ifindfilter.h 中声明:
#ifndef IFINDFILTER_H
#define IFINDFILTER_H
#include "find_global.h"
#include "textfindconstants.h"
QT_BEGIN_NAMESPACE
class QWidget;
class QSettings;
class QKeySequence;
QT_END_NAMESPACE
namespace Find {
class FIND_EXPORT IFindFilter : public QObject
{
Q_OBJECT
public:
virtual ~IFindFilter() {}
virtual QString id() const = 0;
virtual QString displayName() const = 0;
///
virtual bool isEnabled() const = 0;
virtual bool canCancel() const = 0;
virtual void cancel() = 0;
virtual QKeySequence defaultShortcut() const;
virtual bool isReplaceSupported() const { return false; }
virtual FindFlags supportedFindFlags() const;
virtual void findAll(const QString &txt, Find::FindFlags findFlags) = 0;
virtual void replaceAll(const QString &txt, Find::FindFlags findFlags)
{ Q_UNUSED(txt) Q_UNUSED(findFlags) }
virtual QWidget *createConfigWidget() { return 0; }
virtual void writeSettings(QSettings *settings) { Q_UNUSED(settings) }
virtual void readSettings(QSettings *settings) { Q_UNUSED(settings) }
signals:
void changed();
};
} // namespace Find
#endif // IFINDFILTER_H 通过实现IFindFilter接口,然后将其实例添加到对象池,我们就可以注册一个新的文件过滤器,这意味着我们将会在前面提到的查找对话框的“范围”下拉框中找到新的一项。
自定义过滤器
假设我们需要一个自定义过滤器,用于在已打开工程中查找一个给定的头文件。那么,我们可以根据下面的几个步骤来理解如何编写这个查找过滤器。
1. 声明HeaderFilter类
首先,我们需要声明一个实现了Find::IFindFilter接口的类,也就是HeaderFilter。这个类定义如下:
#ifndef HEADERFILTER_H
#define HEADERFILTER_H
#include
class HeaderFilterData;
class HeaderFilter : public Find::IFindFilter
{
Q_OBJECT
public:
HeaderFilter();
~HeaderFilter();
QString id() const;
QString displayName() const;
bool isEnabled() const;
bool canCancel() const;
void cancel();
QKeySequence defaultShortcut() const;
void findAll(const QString &txt, Find::FindFlags findFlags);
QWidget *createConfigWidget();
private:
HeaderFilterData *d;
};
#endif // HEADERFILTER_H 2. 实现 HeaderFilter 类
构造函数和析构函数都是空白的。我们会在后面详细了解过IFindFilter的工作过程之后再来填入更多的代码。
struct HeaderFilterData
{
};
HeaderFilter::HeaderFilter()
{
d = new HeaderFilterData;
}
HeaderFilter::~HeaderFilter()
{
delete d;
} id()函数用于该 filter 的唯一标示符:
QString HeaderFilter::id() const
{
return "HeaderFilter";
} displayName()函数用于在范围下拉框中显示:
QString HeaderFilter::displayName() const
{
return tr("Header Filter");
} isEnabled()函数返回 bool 值,表示该过滤器是否可用。在这个例子中,我们希望在 Qt Creator 加载了项目之后,该过滤器可用,否则不可用。为了更进一步了解该函数的作用,我们必须了解ProjectExplorer命名空间。现在,我们简单的将其返回值设置为 true,等到学习过 ProjectExplorer 命名空间之后再对此函数作进一步完善。
bool HeaderFilter::isEnabled() const
{
return true;
} canCancel()和cancel()函数用于表示该过滤器能够被取消。这里我们也是用最简单的代码:
bool HeaderFilter::canCancel() const
{
return true;
}
void HeaderFilter::cancel()
{
// Do nothing
} defaultShortcut()函数返回与此过滤器相关的快捷键。用户按下该快捷键之后,查找对话框将自动打开,并且该过滤器被选中。在本例中,我们返回一个非法快捷键:
QKeySequence HeaderFilter::defaultShortcut() const
{
return QKeySequence();
} createConfigWidget()函数返回一个用于配置的组件。这个组件将显示在查找对话框的最下方(注意本文开始的查找对话框图片中,最下方的“文件模式”的位置)。在本例中,我们不需要对 header filter 作任何配置,因此使用一个 label 显示即可:
QWidget *HeaderFilter::createConfigWidget()
{
return (new QLabel("This is a header filter"));
} findAll()函数用于实现真实的“查找”操作。我们需要了解ProjectExplorer、TextEditor、Find和Core::Utils这几个命名空间之后才能编写实际代码。所以现在,我们的findAll()函数还是空白的:
void HeaderFilter::findAll(const QString &text, Find::FindFlags findFlags)
{
// Do nothing
} 3. 实现HeaderFilterPlugin代码
HeaderFilterPlugin代码同前面一样,我们只需修改 initialize()函数:
bool HeaderFilterPlugin::initialize(const QStringList& args, QString *errMsg)
{
Q_UNUSED(args);
Q_UNUSED(errMsg);
addAutoReleasedObject(new HeaderFilter);
return true;
} 4. 测试
将我们的代码编译之后,重启 Qt Creator。我们之前仅仅使用了 coreplugin 这个插件,而现在,我们需要使用 find。这需要修改 pro 文件:
QTC_SOURCE = E:/codelibs/QtCreator/qt-creator-2.2.1-src QTC_BUILD = E:/codelibs/QtCreator/build/ TEMPLATE = lib TARGET = HeaderFilterPlugin IDE_SOURCE_TREE = $QTC_SOURCE IDE_BUILD_TREE = $QTC_BUILD PROVIDER = GalaxyWorld DESTDIR = $QTC_BUILD/lib/qtcreator/plugins/GalaxyWorld LIBS += -L$QTC_BUILD/lib/qtcreator/plugins/Nokia include($QTC_SOURCE/src/qtcreatorplugin.pri) include($QTC_SOURCE/src/plugins/coreplugin/coreplugin.pri) include($QTC_SOURCE/src/plugins/find/find.pri) HEADERS = HeaderFilterPlugin.h HeaderFilter.h SOURCES = HeaderFilterPlugin.cpp HeaderFilter.cpp OTHER_FILES = HeaderFilterPlugin.pluginspec
注意其中添加了 find.pri 一行。
现在,我们可以在查找对话框中看到新增加的 Header Filter 一项。注意在范围下拉框中的显示以及对话框下方的配置组件。

现在,由于我们的findAll()函数没有实现,我们仅仅为对话框提供了一个没有“查找”功能的界面。在后面的章节中,我们将继续完成这个插件。
2 评论
我晕了,好复杂啊
复杂的系统就有复杂的架构呗…嘻嘻