最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
QtCreator插件開發(fā)(三)——QtCreator架構(gòu)

QtCreator插件開發(fā)(三)——QtCreator架構(gòu)

一、QtCreator架構(gòu)簡(jiǎn)介

QtCreator的核心就是一個(gè)插件加載器,其所有功能都是通過插件實(shí)現(xiàn)的。
QtCreator架構(gòu)如下:
QtCreator插件開發(fā)(三)——QtCreator架構(gòu)
QtCreator的核心功能由Core Plugin (Core::ICore)實(shí)現(xiàn)。
插件管理器(ExtensionSystem::PluginManager)對(duì)插件協(xié)作提供了簡(jiǎn)單方式,允許插件為其他插件擴(kuò)展提供鉤子。
PluginManager負(fù)責(zé)插件的加載,管理,銷毀等工作。Core插件是QtCreator最基礎(chǔ)的插件,提供了向界面增加菜單等功能。
QtCreator的核心系統(tǒng)是由PluginManager和Core插件構(gòu)成。PluginManager負(fù)責(zé)插件的管理工作,Core負(fù)責(zé)提供QtCreator的最小功能集合。PluginManager將Core當(dāng)做普通插件進(jìn)行加載。對(duì)于自定義插件,Core是一個(gè)基礎(chǔ)功能庫,使用Core可以擴(kuò)展QtCreator的功能。
QtCreator的所有功能,全是由插件實(shí)現(xiàn)的,使用插件機(jī)制的優(yōu)點(diǎn)是簡(jiǎn)化了頂層業(yè)務(wù),即插件管理工作的邏輯,缺點(diǎn)是增加了加載插件的復(fù)雜度,由于Core插件需要被其他插件依賴,所以qtcreator在插件加載時(shí)就必須要考慮插件之間的依賴性。

創(chuàng)新互聯(lián)是工信部頒發(fā)資質(zhì)IDC服務(wù)器商,為用戶提供優(yōu)質(zhì)的雙線服務(wù)器托管服務(wù)

二、插件模塊

1、插件模塊

最基本的插件是一個(gè)共享庫,從開發(fā)者的角度,插件是一個(gè)模塊。
插件模塊的實(shí)現(xiàn)需要滿足以下功能:
A、在一個(gè)類中實(shí)現(xiàn)ExtensionSystem::IPlugin接口。
B、使用Q_EXPORT_PLUGIN宏導(dǎo)出插件類。
C、提供一個(gè)pluginspec插件描述文件,用于描述插件的元信息。
D、向其它插件暴露一個(gè)或多個(gè)對(duì)象。
E、查找其它插件暴露出來的可用的一個(gè)或多個(gè)對(duì)象。
插件都需要繼承IPlugin的接口,插件是由描述文件和繼承IPlugin的類庫組成。
描述文件內(nèi)容如下:


    Scorpio.org
    (C) 2010-2011 Scorpio.org
    Do anything you want.
    A plugin that does nothing.
    http://www.scorpio.net
    
        
    

插件描述文件描述了插件的基本信息,用于被插件管理器加載。最后一行描述了插件所依賴的其它插件,PluginManager會(huì)根據(jù)插件之間的依賴關(guān)系決定加載順序。
IPlugin是插件的基類接口,主要接口如下:

//初始化函數(shù),在插件被加載時(shí)會(huì)調(diào)用
bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
//在所有插件的initialize函數(shù)被調(diào)用后,調(diào)用該函數(shù),此時(shí)該插件依賴的插件已經(jīng)初始化完成
void IPlugin::extensionsInitialized()
//在所有插件的extensionsInitialized函數(shù)調(diào)用完成以后進(jìn)行調(diào)用   
bool IPlugin::delayedInitialize()

2、暴露對(duì)象

暴露對(duì)象是存在于插件管理器對(duì)象池中的對(duì)象。
插件暴露出的對(duì)象會(huì)加入到PluginManager的對(duì)象池。PluginManager的allObjects()函數(shù)用于獲取對(duì)象池中所有QObject對(duì)象的指針列表。下面的代碼演示了如何在QListWidget組件中列出對(duì)象池中所有的對(duì)象:

#include 

ExtensionSystem::PluginManager* pm
         = ExtensionSystem::PluginManager::instance();

QList objects = pm->allObjects();
QListWidget* listWidget = new QListWidget;

Q_FOREACH(QObject* obj, objects)
{
    QString objInfo = QString("%1 (%2)")
                      .arg(obj->objectName())
                      .arg(obj->metaObject()->className());
    listWidget->addItem(objInfo);
}

將DoNothing插件中doNothing函數(shù)修改如下:

#include 

void DoNothingPlugin::doNothing()
{
    ExtensionSystem::PluginManager* pm
            = ExtensionSystem::PluginManager::instance();

    QList objects = pm->allObjects();
    QListWidget* listWidget = new QListWidget();
    Q_FOREACH(QObject* obj, objects)
    {
        QString objInfo = QString(QString::fromUtf8("%1 (%2)"))
                .arg(obj->objectName())
                .arg(QString::fromUtf8(obj->metaObject()->className()));
        listWidget->addItem(objInfo);
    }
    listWidget->resize(300,600);
    listWidget->show();
}

QtCreator插件開發(fā)(三)——QtCreator架構(gòu)
一個(gè)對(duì)外暴露的對(duì)象是由一個(gè)插件對(duì)外暴露的QObject(或其子類)的實(shí)例,暴露對(duì)象存在于對(duì)象池中,并且可供其它插件使用。

3、如何從插件中暴露對(duì)象

有三種方法從插件中暴露一個(gè)對(duì)象:
A、IPlugin::addAutoReleasedObject(QObject)
B、IPlugin::addObject(QObject
)
C、PluginManager::addObject(QObject)
IPlugin::addObject()和IPlugin::addAutoReleasedObject()其實(shí)都是調(diào)用的PluginManager::addObject()函數(shù)。建議使用IPlugin的函數(shù)添加對(duì)象。addAutoReleasedObject()和addObject()的唯一區(qū)別是,前者添加的對(duì)象會(huì)在插件銷毀的時(shí)候自動(dòng)按照注冊(cè)順序的反向順序從對(duì)象池中移除并delete。
在任意時(shí)刻,都可以使用IPlugin::removeObject(QObject
)函數(shù)將對(duì)象從對(duì)象池中移除。

4、需要暴露的對(duì)象

插件可以暴露任何對(duì)象。通常,被其它插件使用了某些功能的對(duì)象會(huì)被暴露。QtCreator中,功能通過接口的方式定義。
下面是其中一些接口:
Core::INavigationWidgetFactory
Core::IEditor
Core::IOptionsPage
Core::IOutputPane
Core::IWizard
如果一個(gè)插件包含實(shí)現(xiàn)了接口的對(duì)象,那么這個(gè)對(duì)象就應(yīng)該被暴露出來。例如,一個(gè)插件中的某個(gè)類實(shí)現(xiàn)了INavigationWidgetFactory接口,并且暴露出來,那么Core就會(huì)自動(dòng)把這個(gè)類提供的組件當(dāng)做導(dǎo)航組件顯示出來。創(chuàng)建一個(gè)導(dǎo)航欄插件TableNav,通過實(shí)現(xiàn)?Core::INavigationWidgetFactory接口,將一個(gè)簡(jiǎn)單的QTableWidget當(dāng)做導(dǎo)航組件。
Core::INavigationWidgetFactory接口實(shí)現(xiàn)如下:
NavWidgetFactory.h文件:

#ifndef NAVWIDGETFACTORY_H
#define NAVWIDGETFACTORY_H

#include 
#include 
using namespace Core;

class NavWidgetFactory : public Core::INavigationWidgetFactory
{
public:
    NavWidgetFactory();
    ~NavWidgetFactory();
    Core::NavigationView createWidget();
    QString displayName() const;
    int priority() const;
    Id id() const;
};

#endif // NAVWIDGETFACTORY_H

NavWidgetFactory.cpp文件:

#include "NavWidgetFactory.h"

#include 

NavWidgetFactory::NavWidgetFactory() { }

NavWidgetFactory::~NavWidgetFactory() { }

Core::NavigationView NavWidgetFactory::createWidget()
{
    Core::NavigationView view;
    view.widget = new QTableWidget(50, 3);
    return view;
}

QString NavWidgetFactory::displayName() const
{
    return QString::fromUtf8("TableNav");
}

int NavWidgetFactory::priority() const
{
    return 0;
}

Id NavWidgetFactory::id() const
{
    return Id::fromName("TableNav");
}

TableNav插件實(shí)現(xiàn)如下:
TableNavPlugin .h文件:

#ifndef TABLENAVPLUGIN_H
#define TABLENAVPLUGIN_H

#include 
#include "NavWidgetFactory.h"

#include 
#include 

class TableNavPlugin : public ExtensionSystem::IPlugin
{
public:
    TableNavPlugin();
    ~TableNavPlugin();
    void extensionsInitialized();
    bool initialize(const QStringList & arguments, QString * errorString);
    void shutdown();
};

#endif // TABLENAVPLUGIN_H

TableNavPlugin .cpp文件:

#include "TableNavPlugin.h"
#include "NavWidgetFactory.h"

#include 
#include 

TableNavPlugin::TableNavPlugin()
{
    // Do nothing
}

TableNavPlugin::~TableNavPlugin()
{
    // Do notning
}

bool TableNavPlugin::initialize(const QStringList& args, QString *errMsg)
{
    Q_UNUSED(args);
    Q_UNUSED(errMsg);
    // Provide a navigation widget factory.
    // Qt Creator’s navigation widget will automatically
    // hook to our INavigationWidgetFactory implementation, which
    // is the NavWidgetFactory class, and show the QTableWidget
    // created by it in the navigation panel.
    //暴露對(duì)象
    addAutoReleasedObject(new NavWidgetFactory);
    return true;
}

void TableNavPlugin::extensionsInitialized()
{
    // Do nothing
}

void TableNavPlugin::shutdown()
{
    // Do nothing
}

Q_EXPORT_PLUGIN(TableNavPlugin)

TableNav插件描述文件如下:


    Scorpio
    (C) 2010-2011 Scorpio.org
    MIT
    Table widget as navigation.
    http://www.scorpio.net
    
        
    

TableNav插件依賴文件如下:

QTC_PLUGIN_NAME = TableNav

QTC_PLUGIN_DEPENDS += \
    coreplugin

TableNav插件工程文件如下:

EMPLATE = lib
TARGET = TableNav
include(../../qtcreatorplugin.pri)
PROVIDER = Scorpio
include(../../plugins/coreplugin/coreplugin.pri)

HEADERS += TableNavPlugin.h \
    NavWidgetFactory.h

SOURCES += TableNavPlugin.cpp \
    NavWidgetFactory.cpp

OTHER_FILES += TableNav.pluginspec \
    TableNav_dependencies.pri

結(jié)果如下:
QtCreator插件開發(fā)(三)——QtCreator架構(gòu)

5、監(jiān)控暴露對(duì)象

當(dāng)使用PluginManager::addObject()添加對(duì)象時(shí),PluginManager就會(huì)發(fā)出objectAdded(QObject)信號(hào)。應(yīng)用程序可以使用objectAdded(QObject)信號(hào)來弄清楚被添加的對(duì)象。
只有插件被初始化后,插件管理器才會(huì)發(fā)出objectAdded(QObject*)信號(hào)。只有被初始化后添加到插件管理器對(duì)象池的插件對(duì)象,才能收到objectAdded()信號(hào)。
通常,連接到objectAdded()信號(hào)的slot會(huì)尋找一個(gè)或多個(gè)已知接口。假設(shè)插件要找的是INavigationWidgetFactory接口,那么連接objectAdded()信號(hào)的槽函數(shù)如下:

void xxxPlugin::slotObjectAdded(QObject * obj)
{
    INavigationWidgetFactory *factory = Aggregation::query(obj);
    if(factory)
    {
        // use it here...
    }
}

6、查找對(duì)象

有時(shí),插件需要在應(yīng)用程序中查找提供了某些功能的對(duì)象。目前,已知查找對(duì)象的方法有兩種:
A、PluginManager::allObjects()函數(shù)返回一個(gè)QList形式的對(duì)象池。
B、通過連接PluginManager::objectAdded()信號(hào),可以知道被暴露的對(duì)象。
假設(shè)需要查找一個(gè)實(shí)現(xiàn)了INavigationWidgetFactory接口的對(duì)象,然后把它添加到一個(gè)QListWidget中顯示出來。那么,可以使用PluginManager::getObjects()函數(shù)。下面是代碼片段:

ExtensionSystem::PluginManager* pm =                            ExtensionSystem::PluginManager::instance();
QList objects
  = pm->getObjects();
QListWidget* listWidget = new QListWidget();
Q_FOREACH(Core::INavigationWidgetFactory* obj, objects)
{
    QString objInfo = QString("%1 (%2)")
                        .arg(obj->displayName())
                        .arg(obj->metaObject()->className());
    listWidget->addItem(objInfo);
}

三、Core插件

1、Core插件簡(jiǎn)介

QtCreator的核心系統(tǒng)由PluginManager和Core插件構(gòu)成。PluginManager負(fù)責(zé)插件的管理工作,將Core插件當(dāng)做普通插件進(jìn)行加載;Core插件負(fù)責(zé)提供QtCreator的最小功能集合,為其它插件提供基礎(chǔ)功能。
QtCreator所有功能由插件實(shí)現(xiàn),優(yōu)點(diǎn)是簡(jiǎn)化了頂層業(yè)務(wù),即插件管理工作的邏輯,只有PlunginManager和Plugin;缺點(diǎn)是增加了加載插件的復(fù)雜度,因?yàn)镃ore基礎(chǔ)庫插件需要被其他插件依賴,所以QtCreator在插件加載時(shí)就必須要考慮插件之間的依賴性。
只包括core、Find、Locator、TextEditor四個(gè)必須插件的QtCreator界面如下:
QtCreator插件開發(fā)(三)——QtCreator架構(gòu)

2、Core插件的功能接口集合

C++?開發(fā)者通常會(huì)將只包含?public純虛函數(shù)的類當(dāng)做接口。在QtCreator中,接口則是擁有一個(gè)或多個(gè)純虛函數(shù)的QObject子類。如果一個(gè)插件實(shí)現(xiàn)了IXXX接口的對(duì)象,那么這個(gè)對(duì)象就應(yīng)該被暴露出來。例如,一個(gè)插件中的某個(gè)類實(shí)現(xiàn)了INavigationWidgetFactory接口,并且暴露出來,那么 Core 就會(huì)自動(dòng)把這個(gè)類提供的組件當(dāng)做導(dǎo)航組件顯示出來。
QtCreator中,功能通過接口的方式定義。Core插件模塊定義了QtCreator的常用功能接口集合,如下:
Core::IOptionsPage
Core::IWizard
Core::IEditor
Core::IEditorFactory
Core::IDocumentFactory
Core::IExternalEditor
Core::IContext
Core::ICore
Core::ICoreListener
Core::IDocument
Core::IFileWizardExtension
Core::IMode
Core::INavigationWidgetFactory
Core::IOutputPane
Core::IVersionControl
功能接口會(huì)在其它插件或Core插件實(shí)現(xiàn),如git插件在GitVersionControl類對(duì)Core::IVersionControl接口進(jìn)行了實(shí)現(xiàn),Core插件在TextDocument類中對(duì)IDocument接口進(jìn)行了實(shí)現(xiàn)。

3、Core插件的源碼

coreplugin.h文件:

#ifndef COREPLUGIN_H
#define COREPLUGIN_H

#include 

namespace Core {
class DesignMode;
namespace Internal {

class EditMode;
class MainWindow;

class CorePlugin : public ExtensionSystem::IPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Core.json")

public:
    CorePlugin();
    ~CorePlugin();

    //必須實(shí)現(xiàn)接口initialize
    bool initialize(const QStringList &arguments, QString *errorMessage = 0);
    //必須實(shí)現(xiàn)接口extensionsInitialized
    void extensionsInitialized();
    bool delayedInitialize();
    ShutdownFlag aboutToShutdown();
    QObject *remoteCommand(const QStringList & /* options */, const QStringList &args);

public slots:
    void fileOpenRequest(const QString&);

private:
    void parseArguments(const QStringList & arguments);

    MainWindow *m_mainWindow;//主窗口
    EditMode *m_editMode;//編輯模式
    DesignMode *m_designMode;//設(shè)計(jì)器模式
};

} // namespace Internal
} // namespace Core

#endif // COREPLUGIN_H

coreplugin.cpp文件:

#include "coreplugin.h"
#include "actionmanager.h"
#include "designmode.h"
#include "editmode.h"
#include "editormanager.h"
#include "fileiconprovider.h"
#include "helpmanager.h"
#include "mainwindow.h"
#include "mimedatabase.h"
#include "modemanager.h"
#include "infobar.h"

#include 

#include 
#include 
#include 

using namespace Core;
using namespace Core::Internal;

CorePlugin::CorePlugin() :
    m_mainWindow(new MainWindow), m_editMode(0), m_designMode(0)
{
}

CorePlugin::~CorePlugin()
{
    if (m_editMode) {
        removeObject(m_editMode);
        delete m_editMode;
    }

    if (m_designMode) {
        if (m_designMode->designModeIsRequired())
            removeObject(m_designMode);
        delete m_designMode;
    }

    // delete FileIconProvider singleton
    delete FileIconProvider::instance();

    delete m_mainWindow;
}

void CorePlugin::parseArguments(const QStringList &arguments)
{
    for (int i = 0; i < arguments.size(); ++i) {
        if (arguments.at(i) == QLatin1String("-color")) {
            const QString colorcode(arguments.at(i + 1));
            m_mainWindow->setOverrideColor(QColor(colorcode));
            i++; // skip the argument
        }
        if (arguments.at(i) == QLatin1String("-presentationMode"))
            ActionManager::setPresentationModeEnabled(true);
    }
}

bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
    qsrand(QDateTime::currentDateTime().toTime_t());
    parseArguments(arguments);
    const bool success = m_mainWindow->init(errorMessage);
    if (success) {
        m_editMode = new EditMode;
        addObject(m_editMode);
        //切換到編輯模式
        ModeManager::activateMode(m_editMode->id());
        m_designMode = new DesignMode;
        InfoBar::initializeGloballySuppressed();
    }

    // Make sure we respect the process's umask when creating new files
    Utils::SaveFile::initializeUmask();

    return success;
}

void CorePlugin::extensionsInitialized()
{
    m_mainWindow->mimeDatabase()->syncUserModifiedMimeTypes();
    if (m_designMode->designModeIsRequired())
        addObject(m_designMode);
    m_mainWindow->extensionsInitialized();
}

bool CorePlugin::delayedInitialize()
{
    HelpManager::instance()->setupHelpManager();
    return true;
}

QObject *CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args)
{
    IDocument *res = m_mainWindow->openFiles(
                args, ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers));
    m_mainWindow->raiseWindow();
    return res;
}

void CorePlugin::fileOpenRequest(const QString &f)
{
    remoteCommand(QStringList(), QStringList(f));
}

ExtensionSystem::IPlugin::ShutdownFlag CorePlugin::aboutToShutdown()
{
    m_mainWindow->aboutToShutdown();
    return SynchronousShutdown;
}

Q_EXPORT_PLUGIN(CorePlugin)
Core插件對(duì)Core::IMode進(jìn)行了不同實(shí)現(xiàn),如EditMode、DesignMode,并在initialize函數(shù)加載了相應(yīng)功能。

四、插件與核心系統(tǒng)的通信

1、核心系統(tǒng)如何加載插件

在main函數(shù)中由ExtensionSystem::PluginManager插件管理器加載。
pluginManager.loadPlugins();
void PluginManager::loadPlugins()函數(shù)調(diào)用了void PluginManagerPrivate::loadPlugins()函數(shù)。

void PluginManagerPrivate::loadPlugins()
{
    //獲取待加載的插件,loadQueue根據(jù)插件批次依賴關(guān)系進(jìn)行排序
    QList queue = loadQueue();
    //加載插件
    foreach (PluginSpec *spec, queue) {
        loadPlugin(spec, PluginSpec::Loaded);
    }
    //初始化插件
    foreach (PluginSpec *spec, queue) {
        loadPlugin(spec, PluginSpec::Initialized);
    }
    QListIterator it(queue);
    it.toBack();
    while (it.hasPrevious()) {
        loadPlugin(it.previous(), PluginSpec::Running);
    }
    emit q->pluginsChanged();
}

2、插件如何使用核心系統(tǒng)為軟件擴(kuò)展功能

自定義插件使用Core插件提供的功能向界面添加菜單代碼如下:

bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
{
    Q_UNUSED(args);
    Q_UNUSED(errMsg);

    Core::ActionManager* am = Core::ICore::instance()->actionManager();

    // Create a DoNothing menu
    Core::ActionContainer* ac = am->createMenu("DoNothingPlugin.DoNothingMenu");
    ac->menu()->setTitle(QString::fromUtf8("DoNothing"));
    // Create a command for "About DoNothing".
    Core::Command* cmd = am->registerAction(
                new QAction(this),
                "DoNothingPlugin.AboutDoNothing",
                Core::Context(Core::Constants::C_GLOBAL));
    cmd->action()->setText(QString::fromUtf8("About DoNothing"));
    connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(doNothing()));
    // Insert the "DoNothing" menu between "Window" and "Help".
    QMenu* helpMenu = am->actionContainer(Core::Constants::M_HELP)->menu();
    QMenuBar* menuBar = am->actionContainer(Core::Constants::MENU_BAR)->menuBar();
    menuBar->insertMenu(helpMenu->menuAction(), ac->menu());
    // Add the "About DoNothing" action to the DoNothing menu
    ac->addAction(cmd);

    return true;
}

DoNothing插件在initialize函數(shù)中使用Core插件的Core::ActionManager、Core::ActionContainer、Core::Command功能向主界面菜單欄添加菜單。

Git插件使用Core插件提供的功能向主界面菜單欄的git菜單提供菜單和菜單項(xiàng),代碼如下:

//register actions
    Core::ActionContainer *toolsContainer =
        Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);

    Core::ActionContainer *gitContainer = Core::ActionManager::createMenu("Git");
    gitContainer->menu()->setTitle(tr("&Git"));
    toolsContainer->addMenu(gitContainer);
    m_menuAction = gitContainer->menu()->menuAction();

    /*  "Current File" menu */
    Core::ActionContainer *currentFileMenu = Core::ActionManager::createMenu(Core::Id("Git.CurrentFileMenu"));
    currentFileMenu->menu()->setTitle(tr("Current &File"));
    gitContainer->addMenu(currentFileMenu);

五、聚合實(shí)現(xiàn)

聚合由Aggregation命名空間提供,提供了一種將不同類型的QObject粘合在一起的能力,因此可以將不同類型對(duì)象相互轉(zhuǎn)換。使用Aggregation命名空間中的類和函數(shù),就可以綁定相關(guān)對(duì)象到一個(gè)單獨(dú)實(shí)體(聚合)。被綁定到聚合中的對(duì)象能夠從聚合轉(zhuǎn)換為不同的對(duì)象類類型。

1、聚合的傳統(tǒng)實(shí)現(xiàn)

如果想要一個(gè)對(duì)象提供兩個(gè)接口的實(shí)現(xiàn),實(shí)現(xiàn)代碼如下:

class Interface1
{
    ....
};
Q_DECLARE_INTERFACE("Interface1", "Interface1");

class Interface2
{
    ....
};
Q_DECLARE_INTERFACE("Interface2", "Interface2");

class Bundle : public QObject,
               public Interface1,
               public Interface2
{
    Q_OBJECT
    Q_INTERFACES(Interface1 Interface2)
    ....
};

Bundle bundle;

對(duì)象bundle同時(shí)實(shí)現(xiàn)了Interface1和Interface2??梢允褂妙愋娃D(zhuǎn)換運(yùn)算符,將bundle轉(zhuǎn)換成Interface1或者Interface2:

Interface1* iface1Ptr = qobject_cast(&bundle);
Interface2* iface2Ptr = qobject_cast(&bundle);

2、QtCreator實(shí)現(xiàn)方式

QtCreator的Aggregation庫提供了一種更加簡(jiǎn)潔的方式,來定義接口,然后將其打包成一個(gè)對(duì)象。創(chuàng)建Aggregation::Aggregate實(shí)例,然后將對(duì)象添加進(jìn)該對(duì)象。加入聚合的每一個(gè)對(duì)象都可以實(shí)現(xiàn)一個(gè)接口。下面的代碼顯示了如何創(chuàng)建聚合。

#include 

class Interface1 : public QObject
{
    Q_OBJECT
public:
    Interface1() { }
    ~Interface1() { }
};

class Interface2 : public QObject
{
    Q_OBJECT
public:
    Interface2() { }
    ~Interface2() { }
};

Aggregation::Aggregate bundle;
bundle.add(new Interface1);
bundle.add(new Interface2);

聚合實(shí)例bundle現(xiàn)在有兩個(gè)接口的實(shí)現(xiàn)。如果需要轉(zhuǎn)換成相應(yīng)接口,可以使用如下代碼:

Interface1* iface1Ptr = Aggregation::query(&bundle);
Interface2* iface2Ptr = Aggregation::query(&bundle);
利用聚合,可以多次添加具有相同接口的多個(gè)對(duì)象。例如:
Aggregation::Aggregate bundle;
bundle.add(new Interface1);
bundle.add(new Interface2);
bundle.add(new Interface1);
bundle.add(new Interface1);
QListgt; iface1Ptrs =      Aggregation::query_all(&bundle);

使用Aggregation的另一優(yōu)點(diǎn)是,delete聚合中的任一對(duì)象,都可以將整個(gè)聚合delete掉。例如:

Aggregation::Aggregate* bundle = new Aggregation::Aggregate;
bundle->add(new Interface1);
bundle->add(new Interface2);

Interface1* iface1Ptr = Aggregation::query(bundle);
delete iface1Ptr;
// 同時(shí)會(huì) delete 這個(gè) bundle 及其中所有對(duì)象
// 等價(jià)于 delete bundle

網(wǎng)站欄目:QtCreator插件開發(fā)(三)——QtCreator架構(gòu)
轉(zhuǎn)載注明:http://fisionsoft.com.cn/article/gpccjg.html