Qt 插件框架

近来学习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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,956评论 25 709
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,025评论 3 119
  • 第十九品 法界通化分 须菩提。于意云何。若有人满三千大千世界七宝。以用布施。是人以是因缘。得福多不。如是。世尊。此...
    笑看流年阅读 485评论 0 0
  • 晚睡,21世纪以来,人类社会的病。 在平时的闲聊话题中,关于晚睡,是我所在的社交圈里面人的常态。 大家真的很努力呢...
    不负明月_只争朝夕阅读 206评论 0 0
  • 大家好,我是来自武汉的deviche,目前关注安卓技术。来简书这么久,看了很多不错的博客,希望和大家学习交流。 1...
    deviche阅读 312评论 0 0