zoukankan      html  css  js  c++  java
  • QT插件开发方式(没看懂)

    创建一个QT的库项目,删除自动生成的.h和.cpp文件,添加一个接口定义.h文件和一个接口实现类(一个.h一个.cpp).代码如下:

    1.接口文件源码

    #ifndef PLUGININTERFACE_H
    #define PLUGININTERFACE_H

    #include <QString>


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

    QT_BEGIN_NAMESPACE
    Q_DECLARE_INTERFACE(EchoInterface, "com.hollysys.plugin.EchoIntrface/1.0");
    QT_END_NAMESPACE


    #endif

    2.接口实现类头文件

    #ifndef PLUGIN_H
    #define PLUGIN_H

    //#include "plugin_global.h"
    #include <QObject>
    #include "plugininterface.h"

    class Plugin : public QObject, EchoInterface
    {
     Q_OBJECT
     Q_INTERFACES(EchoInterface)
    public:
     Plugin();
     ~Plugin();
    public:
     QString echo(const QString &message);


    };

    #endif // PLUGIN_H

    3.接口实现类cpp文件

    #include "plugin.h"
    #include <QtGui>


    Plugin::Plugin()
    {

    }

    Plugin::~Plugin()
    {

    }

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

    Q_EXPORT_PLUGIN2("echoPlugin", Plugin);

    编译生成dll格式的插件.这里可能会遇到LNK2001错误,因为插件接口定义依赖于QT的元数据,而在代码中手动添加Q_OBJECT宏后,编译器不会自动为我们生成moc_XXXX.cpp文件,因此需要使用命令行生成moc元数据文件:cmd-->cd 源码所在命令 -->moc -o moc_XXXX.cpp XXXX.h.这样就可以手动创建出moc元数据文件,解决LNK2001编译错误.

    建立一个GUI测试项目,代码如下:

    #include "test.h"
    #include <QtGui>
    #include <QMessageBox>
    #include <QDir>

    Test::Test(QWidget *parent, Qt::WFlags flags)
     : QMainWindow(parent, flags)
    {
     ui.setupUi(this);
     QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(ButtonClicked()));
     loadPlugin();
    }

    Test::~Test()
    {

    }

    bool Test::loadPlugin()
    {
     QDir pluginsDir(qApp->applicationDirPath());
     foreach (QString filename, pluginsDir.entryList(QDir::Files))
     {
      QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename));
      QObject *plugin = pluginLoader.instance();
      if(plugin)
      {
       echoInterface = qobject_cast<EchoInterface *>(plugin);//echoInterface是成员变量
       if(echoInterface)
        return true;
      }
     }
    }

    void Test::ButtonClicked()
    {
     QString plugin = ui.lineEdit->text();
     QMessageBox::information(NULL, "", echoInterface->echo(plugin));
    }

    分析代码可见,这里对所有与exe文件同目录的文件尝试加载插件,如果加载成功则返回.代码实现非常简洁.在正式开发中可将已加载的插件接口存放在列表中,在需要的时候依次调用即可.

    另外如果想获取插件中类定义的元数据,可以使插件接口类从QObject继承,并使用Q_CLASSINFO宏添加键值对,如Q_CLASSINFO("Author**", "Henreash**").并从主程序中使用插件对象元数据获取这些键值对:

     const QMetaObject *mo = echoInterface->metaObject();
     for(int i = 0; i < mo->classInfoCount(); i++)
     {
      qDebug() << mo->classInfo(i).name() << mo->classInfo(i).value();
     }

    使用这个机制可以在定义插件类的时候向主程序传递一些特殊信息.

    测试发现,如果在插件接口类中定义一个静态变量,那么这个静态变量在插件中的地址和在主程序中的地址是不相同的.

    http://blog.csdn.net/henreash/article/details/7264489

  • 相关阅读:
    面试题
    iOS 两种方法实现左右滑动出现侧边菜单栏 slide view
    进程、线程、多线程相关总结
    iOS开发
    播放 视频
    delphi控件属性大全-详解-简介
    Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值
    FastReport 使用说明
    delphi的取整函数round、trunc、ceil和floor
    cxGrid 速度
  • 原文地址:https://www.cnblogs.com/findumars/p/5290145.html
Copyright © 2011-2022 走看看