在QtCreator中可以显示多个页面,它通过左边的按钮进行页面切换,这里就扩展核心插件的页面接口,使它可以通过插件方式添加页面,并通过左侧的按键进行页面切换。
1、页面接口
1.1、FancyPage页面类
创建 FancyPage 类型,头文件如下:
#ifndef FANCYPAGE_H
#define FANCYPAGE_H
#include <QObject>
#include "core_global.h"
#include <QPushButton>
namespace Core {
class CORE_EXPORT FancyPage : public QObject
{
Q_OBJECT
public:
explicit FancyPage(QObject *parent = nullptr);
QPushButton *pageButton();
QWidget *pageWidget();
private:
QPushButton *m_pageButton;
QWidget *m_pageWidget;
protected:
void setButtonName(const QString &text);
void setWidget(QWidget *widget);
signals:
};
}
#endif // FANCYPAGE_H
这个类用于创建其他页面,它包含一个按钮和一个Widget控件,按钮显示在主页面的左侧,用于点击是切换页面。
1.2、实例化页面
创建其他页面继承自FancyPage类,如下创建了两个页面:
- Home页面
#ifndef HOMEPAGE_H
#define HOMEPAGE_H
#include <coreplugin/fancypage.h>
class HomePage : public Core::FancyPage
{
public:
HomePage();
};
#endif // HOMEPAGE_H
这个页面继承FancyPage,在该类中实现Home页面的窗体控件。
- Tool页面
#ifndef TOOLPAGE_H
#define TOOLPAGE_H
#include <coreplugin/fancypage.h>
class ToolPage : public Core::FancyPage
{
public:
ToolPage();
};
#endif // TOOLPAGE_H
Tool页面也是一样继承FancyPage,用于创建Tool页面窗体。
2、加载页面
上面两个创建好的页面,需要添加到主界面布局中,主要通过以下方式进行加载:
- 先在插件初始化时候把页面对象通过addObject注册到插件管理器的Object pool中,其官方参考文档说明:https://doc.qt.io/qtcreator-extending/pluginmanager.html
- 然后在Coreplugin插件的extensioninitized中通过allObjects获取所有的object对象并转换为fancyPage,再获取其按钮和Widget控件添加到主界面的layout中;
2.1、创建页面添加到插件管理器
这里直接在Coreplugin的初始化时候添加:
bool CorePlugin::initialize(const QStringList &, QString *)
{
......
//home page load
ExtensionSystem::PluginManager::addObject(new HomePage());
//tool page load
ExtensionSystem::PluginManager::addObject(new ToolPage());
return true;
}
2.2、在主界面加载
(1) 先在主界面添加布局管理器用于整个界面的布局
bool CorePlugin::initialize(const QStringList &, QString *)
{
......
//add page layout
QWidget *mainWidget = new QWidget(mwin);
QHBoxLayout *mainLayout = new QHBoxLayout(mainWidget);
mainWidget->setLayout(mainLayout);
m_pageButtons = new QButtonGroup(mainWidget);
m_pageStacks = new QStackedWidget(mainWidget);
m_buttonLayout = new QVBoxLayout(mainWidget);
m_buttonLayout->setContentsMargins(0,0,0,0);
m_buttonLayout->setSpacing(0);
mainLayout->addLayout(m_buttonLayout);
mainLayout->addWidget(m_pageStacks);
mainLayout->setStretch(0,2);
mainLayout->setStretch(1,8);
mwin->setCentralWidget(mainWidget);
mwin->setMinimumSize(800,600);
m_mainWindow.reset(mwin);
......
}
上述布局是把所有页面切换按键放置在左侧一列,所有的页面放置在Stack控件中布局在右侧,这样在左侧按钮按下是显示不同页面效果。
(2) 加载所有的页面
void CorePlugin::extensionsInitialized()
{
QVector<QObject*> pagesObject = ExtensionSystem::PluginManager::allObjects();
QPushButton *homeBtn = nullptr;
for(QObject* objPage:pagesObject){
FancyPage *page = qobject_cast<FancyPage*>(objPage);
if(!page->pageWidget()){
continue;
}
qDebug()<<" pages button add:"<<page->pageButton()->text();
if(page->pageButton()->objectName() == "Home"){
homeBtn = page->pageButton();
}
m_pageButtons->addButton(page->pageButton());
m_buttonLayout->addWidget(page->pageButton());
m_pageStacks->addWidget(page->pageWidget());
connect(page->pageButton(),&QPushButton::clicked,[=](){
m_pageStacks->setCurrentWidget(page->pageWidget());
page->pageButton()->setChecked(true);
});
//remove from plugin pool
connect(this, &IPlugin::destroyed, this, [=]{
ExtensionSystem::PluginManager::removeObject(objPage);
});
}
//init page
homeBtn->setChecked(true);
m_buttonLayout->addStretch();
}
以上是利用Qt插件框架系统的机制,可以从plugin pool中获取所有的之前通过addObject注册的Object对象,转换为实际的页面类型FancyPage后即可获取到对象的按键和Widget控件。