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

  • 相关阅读:
    【Android Developers Training】 105. 显示一个位置地址
    【Android Developers Training】 104. 接受地点更新
    【Android Developers Training】 103. 查询当前地点
    【Android Developers Training】 102. 序言:让你的应用获知地点
    【Android Developers Training】 101. 显示快速联系人挂件(Quick Contact Badge)
    Agent admitted failure to sign using the key
    谷歌大牛Jeff Dean是如何成为互联网战神的
    mount挂载错误
    linux mount (挂载命令)详解
    出现Fatal IO error 11 (资源暂时不可用) on X server :0.0.的可能原因及解决方案
  • 原文地址:https://www.cnblogs.com/findumars/p/5979115.html
Copyright © 2011-2022 走看看