zoukankan      html  css  js  c++  java
  • QT插件开发方式(作者有RemOjbects文档翻译(48)篇)

    创建一个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

  • 相关阅读:
    php多态
    ssl certificate problem: self signed certificate in certificate chain
    test plugin
    open specific port on ubuntu
    junit vs testng
    jersey rest service
    toast master
    use curl to test java webservice
    update folder access
    elk
  • 原文地址:https://www.cnblogs.com/findumars/p/5979115.html
Copyright © 2011-2022 走看看