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

Qt5下通过CMake创建CTK插件的步骤

2017-02-14 15:06 399 查看
这两天一直在看CTK插件的用法,网上资料实在太少,只能通过已有的一些开源工程摸索,过程中遇到很多问题,都是些细节方面的东西,把过程记录下来,方便以后查阅。网上有通过pro文件创建插件的教程,这里只介绍通过CMakeList配置插件的方法。

首先新建一个插件类PluginLoader(名字可以随意起)

#include <ctkPluginActivator.h>
#include <ctkPluginContext.h>

class ServiceOne;

class LoadPlugin : public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_INTERFACES(ctkPluginActivator)

#ifdef HAVE_QT5
Q_PLUGIN_METADATA(IID "org_ctk_example")
#endif

public:
LoadPlugin();
void start(ctkPluginContext *Context);
void stop(ctkPluginContext *Context);

private:
ServiceOne   *m_service;
};


实现类

#include "LoadPlugin_p.h"

#include <QtPlugin>
#include "ServiceOne.h"

LoadPlugin::LoadPlugin():m_service(0)
{

}

void LoadPlugin::start(ctkPluginContext *Context)
{
m_service = new ServiceOne;
Context->registerService(QStringList("Service"), m_service);
}

void LoadPlugin::stop(ctkPluginContext *Context)
{
if (m_service)
{
delete m_service;
m_service = 0;
}
}

#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
Q_EXPORT_PLUGIN2(org_commontk_log, ctkLogPlugin)
#endif
因为Q_EXAPORT_PLUGIN2在Qt5中已经废弃了,这里加个宏来判断。其中ServieOne为服务的实现类,继承自接口IService,接口供外部调用

IService.h:

#include <QObject>

class IService :public QObject
{
Q_OBJECT
public:
virtual void SetParameter(int x) = 0;
virtual int GetParameter() = 0;
};

Q_DECLARE_INTERFACE(IService, "Service")
ServiceOne.h
	
#include "IService.h"

#include "QObject"

class ServiceOne : public IService
{
Q_OBJECT
Q_INTERFACES(IService)
public:
ServiceOne() {}
~ServiceOne() {}

void SetParameter(int x) { m_x = x; }
int GetParameter() { return m_x; }

private:
int m_x;
};


       下面是CMakeList.txt中的内容

project(org_ctk_example)

set(PLUGIN_export_directive "org_ctk_example_EXPORT")

find_package(CTK REQUIRED)

include_directories(
${CTKCore_INCLUDE_DIRS}
${CTKPluginFramework_INCLUDE_DIRS}
)

set(PLUGIN_SRCS
LoadPlugin.cxx
)

# Files which should be processed by Qts moc
set(PLUGIN_MOC_SRCS
LoadPlugin_p.h
IService.h
ServiceOne.h
)

# Qt Designer files which should be processed by Qts uic
set(PLUGIN_UI_FORMS
)

# QRC Files which should be compiled into the plugin
set(PLUGIN_resources
)

#Compute the plugin dependencies
ctkFunctionGetTargetLibraries(PLUGIN_target_libraries)

ctkMacroBuildPlugin(
NAME ${PROJECT_NAME}
EXPORT_DIRECTIVE ${PLUGIN_export_directive}
Hdrs ${Headers}
SRCS ${PLUGIN_SRCS}
MOC_SRCS ${PLUGIN_MOC_SRCS}
UI_FORMS ${PLUGIN_UI_FORMS}
RESOURCES ${PLUGIN_resources}
TARGET_LIBRARIES ${PLUGIN_target_libraries}
)

因为生成CTK插件需要一个qrc文件和MF文件,ctk提供的ctkMacroBuildPlugin工具可以在创建插件工程的同时自动创建这两个文件,不过需要我们在源文件目录下放置两个cmake文件manifest_headers.cmake和target_libraries.cmake,文件内容分别为

manifest_headers.cmake

set(Plugin-Name "CTK Example")
set(Plugin-ActivationPolicy "eager")
Plugin-name为插件名称,可以自己设置。

arget_libraries.cmake:

SET(target_libraries
CTKPluginFramework
)


创建好这两个文件,通过cmake配置我们的工程,在生成目录下就会生成MANIFEST.MF和org_ctk_example_manifest.qrc两个文件了。生成好的插件通过Dependency Walker查看,需要有两个导出函数qt_plugin_instance和qt_plugin_query_metadata,否则说明插件配置有问题(刚开始因为一些细节插件总是生成失败T_T)。

生成成功后就可以加载插件并调用服务了

ctkPluginFrameworkFactory* ctkFrameWorkFactory = new ctkPluginFrameworkFactory;
QSharedPointer<ctkPluginFramework> framework = ctkFrameWorkFactory->getFramework();

try
{
framework->init();

framework->start();

qDebug() << "[Info] ctkPluginFramework start ...";
}
catch (const ctkPluginException &Exception)
{
qDebug() << QObject::tr("Failed to initialize the plug-in framework: ") << Exception.what();
return 1;
}

//install plugin
ctkPluginContext* pluginContext = framework->getPluginContext();
QSharedPointer<ctkPlugin> Plugin = pluginContext->installPlugin(QUrl::fromLocalFile("../liborg_ctk_example.dll"));
Plugin->start(ctkPlugin::START_TRANSIENT);

ctkServiceReference reference = pluginContext->getServiceReference("Service");
IService *test = qobject_cast<IService *>(pluginContext->getService(reference));
test->SetParameter(10);
qDebug() << test->GetParameter();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt 插件 cmake qt5