Qt 插件系统的使用和简单示例

0. 前言

Qt 有自己的插件系统, 使用插件框架开发程序, 便于扩展和管理, 插件实际上是动态库, 个人理解是与动态库的区别是有一个插件管理器, 使用相同的调用约定.

 

1. 环境

Qt 4.8.7 + win10

 

2. 功能

Qt 插件系统的使用和简单示例_第1张图片

这个demo的功能是发送一个Message字符串到插件的函数, 并返回显示
 

3.目录

源码路径: Github下载源码地址

E:PluginApp
│  list.txt
│  PluginApp.pro
│  PluginApp.pro.user
│  
├─EchoPlugin
│      echoplugin.cpp
│      echoplugin.h
│      EchoPlugin.pro
│      main.cpp
│      
└─MainWindow
        echointerface.h
        main.cpp
        MainWindow.pro
        widget.cpp
        widget.h

可以看到, 使用了子项目开发模式, PluginApp 内有两个子项目, EchoPlugin和MainWindow

EchoPlugin: 插件子项目, 生成dll插件

MainWindow: 主窗口 , 调用插件

 

4. 用法

先不说细节, 只讲大概的思路

EchoPlugin

<1> pro中插件的相应配置

<2> 创建插件类, 实现相关的方法

MainWindow

<1> 定义插件的调用头文件, 里面是插件类的声明, 都是虚方法, 用于在创建插件对象时重载

<2> 加载插件类并使用

 

5. 源码

上部分核心代码

MainWindow子项目

echointerface.h 声明插件虚方法的头文件

#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H

#include 

class EchoInterface
{
public:
    virtual ~EchoInterface() {}
    virtual QString echo(const QString &message) = 0;
};

#define EchoInterface_lib "Example.Plugin.EchoInterface"

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_lib)
QT_END_NAMESPACE

#endif // ECHOINTERFACE_H

loadPlugin() 加载插件

bool Widget::loadPlugin()
{
    bool ret = true;
    //获取当前应用程序所在路径
    QDir pluginsDir(qApp->applicationDirPath());
    qDebug() << pluginsDir;

#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
        pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS")
    {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#elif defined(Q_OS_LINUX)
    pluginsDir.cdUp();
#endif
    //切换到插件目录
    pluginsDir.cdUp();
    pluginsDir.cd("plugins");
    qDebug() << pluginsDir;

    //遍历plugins目录下所有文件
    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        qDebug() << fileName;
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));

        QObject *plugin = pluginLoader.instance();
        if (plugin)
        {
            //插件名称
            QString pluginName = plugin->metaObject()->className();
            //对插件初始化
            if(pluginName == "EchoPlugin")
            {
                echoInterface = qobject_cast(plugin);
                if (echoInterface)
                    ret =  true;
                break;
            }
            else
            {
                ret = false;
            }
        }
    }
    return ret;
}

sendEcho 使用插件方法

void Widget::sendEcho()
{
    QString text = echoInterface->echo(lineEdit->text());
    label->setText(text);
}

 

EchoPlugin 插件子项目

echointerface.h

#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H


#include 
#include 
#include "echointerface.h"

class EchoPlugin : public QObject, public EchoInterface
{
    Q_OBJECT
    Q_INTERFACES(EchoInterface)
public:
    explicit EchoPlugin(QObject *parent = 0);
    QString echo(const QString &message);
};

#endif // ECHOPLUGIN_H

echointerface.cpp

#include "echoplugin.h"

EchoPlugin::EchoPlugin(QObject *parent) :
    QObject(parent)
{
}

QString EchoPlugin::echo(const QString &message)
{
    return message;
}

Q_EXPORT_PLUGIN2(EchoPlugin, EchoPlugin)

 

你可能感兴趣的:(Qt,c++,qt,plugin)