Qt 插件框架

近來學(xué)習(xí)QT的插件框架,記錄一些心得

1、插件的好處:

基于插件的設(shè)計(jì)好處很多,把擴(kuò)展功能從框架中剝離出來,降低了框架的復(fù)雜度,讓框架更容易實(shí)現(xiàn).擴(kuò)展功能與框架以一種很松的方式耦合,兩者在保持接口不變的情況下,可以獨(dú)立變化和發(fā)布,將軟件的復(fù)雜度限制在了單個(gè)的插件之中,比較適用與需求不定或是業(yè)務(wù)容易發(fā)生變化的軟件設(shè)計(jì).


image.png

2、構(gòu)建插件框架

2.1主程序

2.1.1接口
//step 1 定義接口
class MainInterface
{
public:
    virtual ~MainInterface(){}
    virtual QString name() = 0;
    virtual QString information() = 0;
   //返回一個(gè)Widget設(shè)置到centerwidget中進(jìn)行顯示  
    virtual QWidget *centerWidget() = 0; 
};
//step 2 聲明接口
#define MainInterface_iid "com.Interface.MainInterface"
Q_DECLARE_INTERFACE(MainInterface, MainInterface_iid)
2.1.2 主程序加載接口
/**
 * @brief MainWindow::loadPlugins 加載插件、插件放在plugins文件夾下
 * @return 返回插件的個(gè)數(shù)
 */
int MainWindow::loadPlugins()
{
    int count  = 0;
    QDir pluginsDir = QDir(qApp->applicationDirPath());
    if(!pluginsDir.cd("plugins")) return -1;
    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if(plugin)
        {
            auto centerInterface = qobject_cast<MainInterface*>(plugin);
            if(centerInterface)
            {
                ++count;
                //加載插件后生成menu
                populateMenus(plugin,centerInterface);
            }
        }
    } 
    return count;
}

/**
 * @brief MainWindow::populateMenus 根據(jù)插件生成menu
 * @param pluginInterface 插件
 * @param i 插件實(shí)現(xiàn)的接口
 */
void MainWindow::populateMenus(QObject * pluginInterface,MainInterface*i )
{
    static auto menu = menuBar()->addMenu("widgets");
    auto act  = new QAction(i->name(),pluginInterface);
    //單擊menu調(diào)用插件
    connect(act,&QAction::triggered,this,&MainWindow::slt_WidgetActionTriggered);
    menu->addAction(act);
}

/**
 * @brief MainWindow::slt_WidgetActionTriggered 單擊menu調(diào)用插件
 */
void MainWindow::slt_WidgetActionTriggered()
{
    auto centerWidget = qobject_cast<MainInterface*>(sender()->parent())->centerWidget();
    setCentralWidget(centerWidget);
}

2.2 接口實(shí)現(xiàn)

class CENTERWIDGETTWOSHARED_EXPORT CenterWidgetTwo
        :public QObject
        ,public MainInterface
{
    Q_OBJECT
    //Q_INTERFACES 宏用于告訴 Qt 該類實(shí)現(xiàn)的接口。
    Q_INTERFACES(MainInterface)
    //Q_PLUGIN_METADATA宏用于描述插件元數(shù)據(jù)
    Q_PLUGIN_METADATA(IID MainInterface_iid) 
    
public:
    CenterWidgetTwo();
    ~CenterWidgetTwo();
    //實(shí)現(xiàn)虛函數(shù)
    virtual QString name() override;
    virtual QString information() override;
    virtual QWidget *centerWidget() override;
};
QWidget *CenterWidgetTwo::centerWidget()
{
    auto btn = new QPushButton("Two");
    return  btn;
}

程序截圖

加載界面1


image.png

加載界面2


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,229評(píng)論 25 708
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,214評(píng)論 3 119
  • 第十九品 法界通化分 須菩提。于意云何。若有人滿三千大千世界七寶。以用布施。是人以是因緣。得福多不。如是。世尊。此...
    笑看流年閱讀 513評(píng)論 0 0
  • 晚睡,21世紀(jì)以來,人類社會(huì)的病。 在平時(shí)的閑聊話題中,關(guān)于晚睡,是我所在的社交圈里面人的常態(tài)。 大家真的很努力呢...
    不負(fù)明月_只爭(zhēng)朝夕閱讀 240評(píng)論 0 0
  • 大家好,我是來自武漢的deviche,目前關(guān)注安卓技術(shù)。來簡(jiǎn)書這么久,看了很多不錯(cuò)的博客,希望和大家學(xué)習(xí)交流。 1...
    deviche閱讀 325評(píng)論 0 0

友情鏈接更多精彩內(nèi)容