美文网首页
Qt 插件框架

Qt 插件框架

作者: 陆不凡 | 来源:发表于2018-10-02 10:59 被阅读0次

    近来学习QT的插件框架,记录一些心得

    1、插件的好处:

    基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现.扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布,将软件的复杂度限制在了单个的插件之中,比较适用与需求不定或是业务容易发生变化的软件设计.


    image.png

    2、构建插件框架

    2.1主程序

    2.1.1接口
    //step 1 定义接口
    class MainInterface
    {
    public:
        virtual ~MainInterface(){}
        virtual QString name() = 0;
        virtual QString information() = 0;
       //返回一个Widget设置到centerwidget中进行显示  
        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 返回插件的个数
     */
    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 根据插件生成menu
     * @param pluginInterface 插件
     * @param i 插件实现的接口
     */
    void MainWindow::populateMenus(QObject * pluginInterface,MainInterface*i )
    {
        static auto menu = menuBar()->addMenu("widgets");
        auto act  = new QAction(i->name(),pluginInterface);
        //单击menu调用插件
        connect(act,&QAction::triggered,this,&MainWindow::slt_WidgetActionTriggered);
        menu->addAction(act);
    }
    
    /**
     * @brief MainWindow::slt_WidgetActionTriggered 单击menu调用插件
     */
    void MainWindow::slt_WidgetActionTriggered()
    {
        auto centerWidget = qobject_cast<MainInterface*>(sender()->parent())->centerWidget();
        setCentralWidget(centerWidget);
    }
    

    2.2 接口实现

    class CENTERWIDGETTWOSHARED_EXPORT CenterWidgetTwo
            :public QObject
            ,public MainInterface
    {
        Q_OBJECT
        //Q_INTERFACES 宏用于告诉 Qt 该类实现的接口。
        Q_INTERFACES(MainInterface)
        //Q_PLUGIN_METADATA宏用于描述插件元数据
        Q_PLUGIN_METADATA(IID MainInterface_iid) 
        
    public:
        CenterWidgetTwo();
        ~CenterWidgetTwo();
        //实现虚函数
        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

    相关文章

      网友评论

          本文标题:Qt 插件框架

          本文链接:https://www.haomeiwen.com/subject/ktwooftx.html