最近用Qt结合OpenCV 进行计算机视觉的开发,在C++开发中,界面设计是比较费力的一项工作,还好Qt提供了一整套GUI的框架和库。很多时候我们的项目比较大,如果以模块或者功能划分,可以独立开发,互不影响,那么插件就可以很好的解决这个问题。
本文主要讲解如何在QT中使用插件方式进行编程。需要对C++和QT开发有一定的基础。
开发环境
Qt5.8
QtCreator
OpenCV4.1
为了方便管理,我建立一个子目录项目 PluginFramework
然后在PluginFramework项目下右键->新子项目->Application->Qt Widgets Application,名称为MainApp,用来读取图片和加载插件。
每一个插件就是一个dll文件,为了好管理,我在PluginFramework项目下右键->新子项目->其他项目->子目录项目,创建名称为Plugins的子项目,所有的插件项目都Plugins子目录下创建。
最后新建一个插件Library,
在Plugins上鼠标右键->新子项目->Library,创建名称为:Edge_Detector_Plugin
具体的项目结构如图:
项目结构整清楚以后,就可以把有关的类库引进来,由于很多地方都会用到OpenCV库,所以我写成了opencv410.pri,放在了项目3rdparty目录中,其他的项目.pro只要include该文件就可以。
# opencv
include($$PWD/../3rdparty/opencv410.pri)
接下来就可介绍如何实现插件开发了。
创建插件接口
创建接口CvPluginInterface,,接口中的方法可以根据需要自行定义,这里定义接口如下,都是一些虚方法,需要子类去实现。需要特别注意的是声明CvPluginInterface为插件接口,并设置唯一标识。
Q_DECLARE_INTERFACE(CvPluginInterface, CVPLUGININTERFACE_IID),
创建完成后我放在了3rdparty,插件库和主程序都需要引用该头文件。
#ifndef CVPLUGIN_H
#define CVPLUGIN_H
#include <QObject>
#include <QWidget>
#include <QString>
#include <opencv2/opencv.hpp>
class CvPluginInterface
{
public:
virtual ~CvPluginInterface() {}
virtual QString title() = 0;
virtual QString version() = 0;
virtual QString description() = 0;
virtual QString help() = 0;
virtual void setupUi(QWidget *parent) = 0;
virtual void processImage(const cv::Mat &inputImage, cv::Mat &outputImage) = 0;
};
// 声明为插件接口
#define CVPLUGININTERFACE_IID "com.computervision.cvplugininterface"
Q_DECLARE_INTERFACE(CvPluginInterface, CVPLUGININTERFACE_IID)
#endif // CVPLUGIN_H
插件接口的实现
以 Edge_Detector_Plugin为例。
插件界面是QWidget类型,这里命名为plugin.ui,类名为PluginGui。
实现插件接口的虚方法
具体的实现类cpp
使用插件
插件生成后,放在主程序的运行目录下,我这里放在plugins的文件夹下,MainApp 启动后就去加载插件。具体逻辑:
- 遍历plugins下所有插件dll,并创建菜单项 点击菜单项
- 实例化该插件,并创建连接,加载的界面显示
- 运行图像处理功能,显示图像结果
插件的加载使用主要有这几个函数:
// 加载插件
QPluginLoader pluginLoader(pluginFile.absoluteFilePath(), this);
// 实例化插件
if(CvPluginInterface *plugin = dynamic_cast<CvPluginInterface*>(pluginLoader.instance())){
// 调动插件方法
plugin ->processImage(originalMat, processedMat);
}
具体的结果展示:
源码我放在了github 上。
https://github.com/zhaitianyong/computer_vision_with_opencv3_and_qt5/tree/master/PluginFramework