您的位置:首页 > 编程语言 > Qt开发

QT插件开发方式

2016-04-15 15:56 435 查看
创建一个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();

 }

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

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

FROM: http://blog.csdn.net/henreash/article/details/7264489
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: