赞
踩
最近在ubuntu中利用qt creator学习qt的插件功能,网上资料较少,记录一下。本文基础建立于在 Qt Creator 上创建 ROS 项目并新建/导入 ROS 包
项目构造如上图,要实现的功能是在rbs_plugins中生成插件文件(.so格式),并在rbs_viz中载入该插件。
在rbs_plugins中添加插件文件:plugininterface.h(接口文件) myplugin.h(自己定义的插件类文件) my_plugin.cpp
plugininterface.h代码如下:
- // rbs_plugins/plugininterface.h
- #ifndef PLUGININTERFACE_H
- #define PLUGININTERFACE_H
-
- #include <QStringList>
- #include <QtPlugin>
- #include <QJsonObject>
-
- class PluginInterface
- {
- public:
- virtual ~PluginInterface() {}
- virtual void doSomething() = 0;
- };
-
- #define PluginInterface_iid "id123" //必须为接口设置id,id随意就行
- Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
-
- #endif // PLUGININTERFACE_H
myplugin.h:
- // rbs_plugins/myplugin.h
- #ifndef MYPLUGIN_H
- #define MYPLUGIN_H
-
- #include <QObject>
- #include "plugininterface.h"
-
- class MyPlugin : public QObject, public PluginInterface
- {
- Q_OBJECT
- Q_INTERFACES(PluginInterface)
- Q_PLUGIN_METADATA(IID "id123") //id必须与刚刚接口的id一致
- public:
- MyPlugin(QObject *parent = nullptr) : QObject(parent) {}
- void doSomething() override; //函数必须实现,不能空着
-
- };
-
- #endif // MYPLUGIN_H
myplugin.cpp:
- // rbs_plugins/myplugin.cpp
- #include "../include/rbs_plugins/myplugin.h"
- #include <QDebug>
-
- void MyPlugin::doSomething()
- {
- qDebug() << "MyPlugin is doing something!";
- }
-
- extern "C" PluginInterface* myplugin_instance() {
- return new MyPlugin;
- }
最重要的是配置cmakelist文件,配置不对会显示meta data载入错误的提示:
- cmake_minimum_required(VERSION 3.0.2)
- project(rbs_plugins)
-
-
- set(CMAKE_AUTOMOC ON)
- set(CMAKE_AUTOUIC ON)
- set(CMAKE_AUTORCC ON)
- set(CMAKE_CXX_STANDARD 17)
-
- find_package(catkin REQUIRED COMPONENTS
- roscpp
- )
- find_package(Qt6 REQUIRED Core Widgets)
- set(QT_LIBRARIES Qt6::Widgets)
- #add
- find_package(VTK REQUIRED)
- include(${VTK_USE_FILE})
-
- catkin_package()
-
- file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ui/*.ui)
- file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc)
- file(GLOB_RECURSE QT_MOC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/../rbs_plugins/ FOLLOW_SYMLINKS include/rbs_viz/*.hpp *.h)
-
- QT_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES})
- QT_WRAP_UI(QT_FORMS_HPP ${QT_FORMS})
- QT_WRAP_CPP(QT_MOC_HPP ${QT_MOC})
-
- file(GLOB_RECURSE QT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/../rbs_plugins/ FOLLOW_SYMLINKS src/*.cpp)
-
-
- add_library(myplugin SHARED ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP})
- target_link_libraries(myplugin PRIVATE Qt6::Core ${QT_LIBRARIES} ${catkin_LIBRARIES} ${VTK_LIBRARIES})
- install(TARGETS myplugin LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}/rbs_plugins)
点击重新构建,可以在项目的该路径下看到插件的生成(catkin_rbs/devel/lib/libmyplugin.so)
将刚刚的接口头文件plugininterface.h移到rbs_viz中的include文件夹中,并在需要载入的cpp文件里#include plugininterface.h,用以下代码进行试验:
- QString pluginPath = "/xxx/xxx/catkin_rbs/devel/lib/libmyplugin.so"; //插件所在路径
- QPluginLoader pluginLoader(pluginPath);
- QObject *plugin = pluginLoader.instance();
-
- if (plugin) {
- myPlugin = qobject_cast<PluginInterface *>(plugin);
- if (myPlugin) {
- qDebug() << "BasePageApi插件加载成功!";
- myPlugin->doSomething();
- myPlugin->doSomething();
- return;
- } else {
- qDebug() << "无法转换为插件接口";
- }
- } else {
- qDebug() << "插件加载失败:" << pluginLoader.errorString();
- }
-
- if (QMessageBox::critical(nullptr, "警告", "BasePageApi插件加载失败!", QMessageBox::Ok) == QMessageBox::Ok) {
- qDebug() << "BasePageApi插件加载失败!!";
- }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。