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
QT插件开发方式(没看懂)的更多相关文章
- 【Luogu】P2765魔术球问题(没看懂的乱搞)
题目链接 这题……讲道理我没看懂. 不过我看懂题解的代码是在干嘛了qwq 题解是zhaoyifan的题解 然后……我来讲讲这个题解好了. 题解把值为i的球拆成了两个,一个编号是i*2,一个编号是i*2 ...
- PAT 甲级 1031 Hello World for U (20 分)(一开始没看懂题意)
1031 Hello World for U (20 分) Given any string of N (≥) characters, you are asked to form the char ...
- QT插件开发方式(作者有RemOjbects文档翻译(48)篇)
创建一个QT的库项目,删除自动生成的.h和.cpp文件,添加一个接口定义.h文件和一个接口实现类(一个.h一个.cpp).代码如下: 1.接口文件源码 #ifndef PLUGININTERFACE_ ...
- 那些年,很多人没看懂的Python内置函数
Python之所以特别的简单就是因为有很多的内置函数是在你的程序"运行之前"就已经帮你运行好了,所以,可以用这个的特性简化很多的步骤.这也是让Python语言变得特别的简单的原因之 ...
- 面试之加分项vue(没看懂,。。。。)
对大部分人来说,掌握Vue.js基本的几个API后就已经能够正常地开发前端网站.但如果你想更加高效地使用Vue来开发,成为Vue.js大师,那下面我要传授的这五招你一定得认真学习一下了.在面试过程很多 ...
- ccf201403-3 记录一个神tmwa了的代码 莫非我没看懂题。。。
#include <string.h> #include<cstdio> #include<stdio.h> #include <iostream> # ...
- 一文看懂JVM内存区域分布与作用
那么我们在开始介绍Java内存区域之前,我们先放一张内存区域的图,方便我们后面介绍的时候可以对照着看. 须知,本文是根据JDK8来介绍的. 程序计数器 首先它是线程私有的,它也称为代码的行号指示器,字 ...
- 小白都能看懂的tcp三次握手
众所周知,TCP在建立连接时需要经过三次握手.许多初学者经常对这个过程感到混乱:SYN是干什么的,怎么一会儿是1一会儿是0?怎么既有大写的ACK又有小写的ack?为什么ACK在第二次握手才开始出现?初 ...
- 小白也能看懂的插件化DroidPlugin原理(二)-- 反射机制和Hook入门
前言:在上一篇博文<小白也能看懂的插件化DroidPlugin原理(一)-- 动态代理>中详细介绍了 DroidPlugin 原理中涉及到的动态代理模式,看完上篇博文后你就会发现原来动态代 ...
随机推荐
- BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )
用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...
- ELK 之一:ElasticSearch 基础和集群搭建
一:需求及基础: 场景: 1.开发人员不能登录线上服务器查看详细日志 2.各个系统都有日志,日志数据分散难以查找 3.日志数据量大,查询速度慢,或者数据不够实时 4.一个调用会涉及到多个系统,难以在这 ...
- 利用java concurrent 包实现日志写数据库的并发处理
一.概述 在很多系统中,往往需要将各种操作写入数据库(比如客户端发起的操作). 最简单的做法是,封装一个公共的写日志的api,各个操作中调用该api完成自己操作日志的入库.但因为入数据库效率比较低,如 ...
- MAMP:在 OSX 中搭建 Apache, MySQL, PHP 环境并本地安装、调试 WordPress
MAMP 这个名字来源于 Macintosh Apache MySQL PHP,显然专门用来在 Mac 环境下搭建 Apache.MySQL.PHP 平台. 虽然 OSX 中已经预装了 Apache ...
- SPOJ 11840. Sum of Squares with Segment Tree (线段树,区间更新)
http://www.spoj.com/problems/SEGSQRSS/ SPOJ Problem Set (classical) 11840. Sum of Squares with Segme ...
- XSS学习笔记(四)-漏洞利用全过程
<script type="text/javascript" reload="1">setTimeout("window.location ...
- Apache Flink
Flink 剖析 1.概述 在如今数据爆炸的时代,企业的数据量与日俱增,大数据产品层出不穷.今天给大家分享一款产品—— Apache Flink,目前,已是 Apache 顶级项目之一.那么,接下来, ...
- 【linux】内核编译
原创,转载时请注明,谢谢.邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http://blog.cs ...
- 基于visual Studio2013解决C语言竞赛题之1071打印工资
题目 解决代码及点评 /************************************************************************/ /* ...
- 六款常用的linux C/C++ IDE
摘要: 一.AnjutaAnjuta是一个多语言的IDE,它最大的特色是灵活,同时打开多个文件,内嵌代码级的调试器(调用gdb),应用程序向导(Application wizards)可以方便的帮助你 ...