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

QT插件开发方式(作者有RemOjbects文档翻译(48)篇)的更多相关文章

  1. QT插件开发方式(没看懂)

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

  2. VS2017上在线和离线安装Qt插件(在线安装)

    版权声明:如需转载,请告知博主并声明出处 https://blog.csdn.net/CLinuxF/article/details/88816436文章目录前言在线安装离线安装(推荐)前言很多朋友喜 ...

  3. VS2010,Qt插件安装使用

    用了几次的QtCreateor,不习惯. 果断换回VS 基本步骤: 1.安装VS2010 2.安装Qt Creator5 3.安装Qt插件 qt-vs-addin-1.2.2-opensource 就 ...

  4. VS2013平台安装Qt插件过程

    1.下载所需安装包: Qt5.3.Qt插件下载地址:http://qt-project.org/downloads. qt-vs-addin-1.1.11-opensource.exe 下载地址:ht ...

  5. 【Win10+eclipse+MinGW+QT安装教程】已有eclipse环境下配置QT插件出错详解

    (纪念一下装了一整天濒临绝望的自己[/doge]) (以下所有下载项一律使用32位) step1:下载安装eclipse.适配的jdk.MinGW和QT 1.下载32位eclipse for c++以 ...

  6. Qt 插件综合编程-基于插件的OpenStreetMap瓦片查看器client(1)-墨卡托投影与坐标控制

    (相关的代码能够从https://github.com/goldenhawking/mercator.qtviewer.git直接克隆) 我们如今是准备做一个C/S架构的地图显示控件.就必定牵扯到坐标 ...

  7. Qt5的插件机制(6)--开发Qt插件时几个重要的宏

    怎样开发Qt插件,能够在Qt Assistant 中搜索"Qt Plugins"或"How to Create Qt Plugins",看看那篇manual中的 ...

  8. Eclipse添加Qt插件

    此文件仅为步骤操作作一个记录,以便以后方便查阅. 1.操作大体参考这个网站:http://blog.csdn.net/defonds/article/details/5013412 2.我的运行环境: ...

  9. [Qt Creator 快速入门] 第9章 国际化、帮助系统和Qt插件

    一.国际化 国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. Qt支持现在 ...

随机推荐

  1. javascript 基础API

    Math.random() 取值范围[0,1)  大于等于0小于1,包括0,不包括1 Math.floor() 向下取整  Math.ceil() 向上取整 第一题:一组数的规则如下:1.1.2.3. ...

  2. linux 硬盘相关命令学习

    summary: 查看硬盘信息:几块硬盘,品牌,容量 查看分区信息 参考资料: Linux下查看磁盘分区命令详解: http://blog.chinaunix.net/uid-26119273-id- ...

  3. 升级ssh编译错误

    升级ssh 编译的时候遇到PAM headers not found,然后需要安装 pam-devel-1.1.1-20.el6.x86_64,自己下载了rpm包,安装报错,然后用yum -y ins ...

  4. Node.js 【Stream之笔记】

    从Node.js API文档中可知, 'A stream is an abstract interface implemented by various objects in Node. For ex ...

  5. PHPCMS 错误日志 Only variables should be passed by ...

    有几个网站是PHPCMS V9做的,但这两天发现一个问题,PHPCMS 的错误日志超过了20M ,后台报警,然后我看了下错误日志,其中两万多行都是一个错误,错误信息如下: 1 <?php exi ...

  6. Demo学习: CustomException

    CustomException 捕获程序发生的异常. 1. 抛出各种异常 procedure TMainForm.UniButton1Click(Sender: TObject); begin PBy ...

  7. what is the “handover” and "soft handover" in mobile communication system?

    Handover: 切换,属于移动通信网络中的技术术语. 所谓切换,就是指当移动台在通话过程中从一个基站覆盖区移动到另一个基站覆盖区,或者由于外界干扰而造成通话质量下降时,必须改变原有的话音信道而转接 ...

  8. FIFO、LRU、OPT这三种置换算法的缺页次数

    考虑下述页面走向: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6 当内存块数量分别为3时,试问FIFO.LRU.OPT这三种置换算法的缺页次数各是多少? 答:缺页定义 ...

  9. Django 下static的配置

    1.添加一个BASE_DIR在setting.py中,如果已存在可不用添加,需引入 import os BASE_DIR = os.path.dirname(os.path.dirname(os.pa ...

  10. Oracle中对象权限与系统权限revoke

    实验: 1.以sys登陆,创建用户test1, test2: 2.授予test1系统权限(带admin option)-connect,授予test1对象权限(带grant option)-selec ...