一、QtCreator导航器简介
导航器位于QtCreator的左侧,可以查看项目、文件、书签等内容。边侧栏side bar则是导航器中的一个组件。红色方框中的就是导航器,而红色短线标示出的是用于选择导航器的下拉框。另外,Qt Creator可以将导航器分成几个部分,正如图中所示,在“项目”下面还有一个“打开文档”面板。
二、创建QtCreator导航器
1、Core::INavigationWidgetFactory
Core::INavigationWidgetFactory是QtCreator暴露出的核心对象之一,定义在 plugins/corelib/inavigationwidgetfactory.h 文件中。
#ifndef INAVIGATIONWIDGET_H
#define INAVIGATIONWIDGET_H
#include <coreplugin/core_global.h>
#include <QtCore/QObject>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QToolButton;
class QKeySequence;
class QWidget;
QT_END_NAMESPACE
namespace Core {
struct NavigationView
{
QWidget *widget;
QList dockToolBarWidgets;
};
class CORE_EXPORT INavigationWidgetFactory : public QObject
{
Q_OBJECT
public:
INavigationWidgetFactory();
virtual ~INavigationWidgetFactory();
virtual QString displayName() const = 0;
virtual int priority() const = 0;
virtual QString id() const = 0;
virtual QKeySequence activationSequence() const;
virtual NavigationView createWidget() = 0;
virtual void saveSettings(int position, QWidget *widget);
virtual void restoreSettings(int position, QWidget *widget);
};
} // namespace Core
#endif // INAVIGATIONWIDGET_H
需要提供导航器的插件必须实现Core::INavigationWidgetFactory接口。除此之外,导航器插件还必须将实现Core::INavigationWidgetFactory接口的类暴露出来。
2、导航器显示组件实现
为了实现导航器,需要创建一个用于导航器显示的组件。本文实现一个用于FTP访问的导航面板。
用户在文本输入框中输入FTP地址,点击 “Go” 按钮之后,FTP的目录内容就会在QTreeView中显示。
#ifndef FTPEXPLORERSIDEBAR_H
#define FTPEXPLORERSIDEBAR_H
#include <QWidget>
struct FtpExplorerSideBarData;
class QUrl;
namespace Ui {
class FtpExplorerSideBar;
}
class FtpExplorerSideBar : public QWidget
{
Q_OBJECT
public:
explicit FtpExplorerSideBar(QWidget *parent = 0);
~FtpExplorerSideBar();
void setUrl(const QUrl& url);
QUrl url() const;
private slots:
void on_goButton_clicked();
private:
FtpExplorerSideBarData* d;
};
#endif // FTPEXPLORERSIDEBAR_H
struct FtpExplorerSideBarData
{
FtpDirModel* model;
Ui::FtpExplorerSideBar ui;
};
FtpExplorerSideBar::FtpExplorerSideBar(QWidget *parent) :
QWidget(parent)
{
d = new FtpExplorerSideBarData;
d->ui.setupUi(this);
d->model = new FtpDirModel(this);
d->ui.ftpView->setModel(d->model);
}
FtpExplorerSideBar::~FtpExplorerSideBar()
{
delete d;
}
void FtpExplorerSideBar::setUrl(const QUrl& url)
{
d->model->setUrl(url);
}
QUrl FtpExplorerSideBar::url() const
{
return d->model->url();
}
void FtpExplorerSideBar::on_goButton_clicked()
{
QUrl url(d->ui.ftpPathEdit->text());
d->model->setUrl(url);
}
3、Core::INavigationWidgetFactory实现
#ifndef FTPVIEWNAVIGATION_H
#define FTPVIEWNAVIGATION_H
#include <coreplugin/inavigationwidgetfactory.h>
class FtpViewNavigationWidgetFactory
: public Core::INavigationWidgetFactory
{
public:
FtpViewNavigationWidgetFactory() { }
~FtpViewNavigationWidgetFactory() { }
Core::NavigationView createWidget();
QString displayName() const;
int priority() const;
QString id() const;
};
#endif // FTPVIEWNAVIGATION_H
Core::INavigationWidgetFactory有四个纯虚函数需要依次实现。
Core::NavigationView FtpViewNavigationWidgetFactory::createWidget()
{
Core::NavigationView view;
view.widget = new FtpExplorerSideBar;
return view;
}
displayName()函数返回side bar的名字。会在导航器下拉框中显示。
QString FtpViewNavigationWidgetFactory::displayName() const
{
return "Ftp View";
}
priority()和id()用于返回组件优先级和ID。
int FtpViewNavigationWidgetFactory::priority() const
{
return 0;
}
QString FtpViewNavigationWidgetFactory::id() const
{
return "Ftp View";
}
4、导航器插件实现
bool FtpViewNavigationPlugin::initialize(const QStringList& args, QString *errMsg)
{
Q_UNUSED(args);
Q_UNUSED(errMsg);
addAutoReleasedObject(new FtpViewNavigationWidgetFactory);
return true;
}
initialize()函数中,创建了一个INavigationWidgetFactory实现的实例,然后将其添加到对象池中。一旦对象被添加到对象池,ExtensionSystem::PluginManager就会发出objectAdded()信号;objectAdded()信号由QtCreator核心监听。一旦核心获得objectAdded()信号,就会利用提供的INavigationWidgetFactory接口的实现,将其添加到导航器面板。
5、保存和恢复侧边栏状态
INavigationWidgetFactory的代码中有两个函数:
virtual void saveSettings(int position, QWidget *widget);
virtual void restoreSettings(int position, QWidget *widget);
saveSettings()函数用于保存组件设置。第二个参数就是该组件的指针。保存位置由Core::ICore:: settings()返回;
restoreSettings()函数用于恢复组件设置。
通过重写saveSettings()函数和restoreSettings()函数,将FTP Path 保存到settings中,第二次打开的时候就可以读取上次输入的值。
void FtpViewNavigationWidgetFactory::saveSettings(int position, QWidget *widget)
{
FtpExplorerSideBar* ftpExp = qobject_cast(widget);
if(!ftpExp)
return;
QSettings *settings = Core::ICore::instance()->settings();
settings->setValue("FtpView.URL", ftpExp->url().toString());
}
void FtpViewNavigationWidgetFactory::restoreSettings(int position, QWidget *widget)
{
FtpExplorerSideBar* ftpExp = qobject_cast(widget);
if(!ftpExp)
return;
QSettings *settings = Core::ICore::instance()->settings();
QString urlStr = settings->value("FtpView.URL").toString();
ftpExp->setUrl( QUrl(urlStr) );
}