主要学习插件的生成和调用方法。
问题:下图中是一个生成库的模块,其中qglobal.h的使用有点疑惑,可以参考下文链接。
一、插件
插件库的生成与使用:
以下链接是共享库和插件都有的一篇博客,仔细阅读,大有裨益!!!
Qt中的动态链接库编程(Q_DECL_IMPORT、Q_DECL_EXPORT)-CSDN博客
从零开始的qplugin之——理解理解_q_interfaces-CSDN博客
摘抄:
1.新建库模版:
2.建立库子类:
3.加载插件:
实例补充:
2024.07.02 插件子项目与主项目结合案例:(均包含界面)
一、新建插件项目: 首先选择新建插件项目:c++ Library ,QPlugin
其中pro文件:注意其中的DETECTOR_PLUGIN_LIBRARY 后边QPlugin接口定义会用到
其次,建立插件基类接口:
#ifndef DETECTORPLUGIN_H
#define DETECTORPLUGIN_H
#include<QObject>
#include"detectorinterface.h"
class DetectorPlugin: public QObject
{
Q_OBJECT
public:
explicit DetectorPlugin(QObject* parent=nullptr);
virtual ~DetectorPlugin();
public:
QWidget* widget_;//插件界面指针
};
QT_BEGIN_NAMESPACE
#define detectorfactory_IID "com.simulator.detectorplugin"
Q_DECLARE_INTERFACE(DetectorPlugin, detectorfactory_IID);
QT_END_NAMESPACE
#endif // DETECTORPLUGIN_H
最后插件子类:注意DETECTOR_PLUGIN_LIBRARY
#ifndef SIMULATERDETECTOR_H
#define SIMULATERDETECTOR_H
#include "simulatordetectorform.h"
#include "detectorplugin.h"
#include"detector_global.h"
class DETECTOR_PLUGIN_EXPORT SimulatorDetector : public DetectorPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.simulator.detectorplugin")
Q_INTERFACES(DetectorPlugin)
public:
explicit SimulatorDetector(QObject *parent = nullptr);
~SimulatorDetector();
private:
SimulatorDetectorForm* pluginWidget_;
};
#endif // SIMULATERDETECTOR_H
二、调用插件,嵌入主界面
注意:这里需要使用绝对路径,否则插件dll无法找到
加载插件:
bool MainWindow::loadPlugin()
{
if(!QLibrary::isLibrary("DetectorPlugin.dll")){
qDebug()<<"not a library";
return false;
}
QDir dir("../../bin/plugins/DetectorPlugin.dll");
qDebug()<<__LINE__ << dir.absolutePath();
QPluginLoader loader(dir.absolutePath());
//QPluginLoader loader("../../bin/plugins/DetectorPlugin.dll");
if (!loader.load()) {
qDebug() << "Error loading plugin:" << loader.errorString();
}
QObject* plugin = loader.instance();
if(plugin){
DetectorPlugin* detectorPlugin = qobject_cast<DetectorPlugin*>(plugin);
QWidget* pluginWidget = detectorPlugin->widget_;
if(pluginWidget){
ui->simulatorTabWidget->addTab(pluginWidget,"Detector");
return true;
}
}
return false;
}
Qt plugin 开发UI界面插件_qt ui插件-CSDN博客
补充2024.06.25 工厂设计模式
1.基类 DetectorBase
#ifndef DETECTORINTERFACE_H
#define DETECTORINTERFACE_H
#include "baselib_global.h"
#include <QObject>
#include <QMutex>
#include <QWaitCondition>
#include "imagerawdataqueue.h"
class ImageDataProducer;
class BASELIB_EXPORT DetectorBase: public QObject
{
Q_OBJECT
public:
explicit DetectorBase(QThread* thread);
virtual ~DetectorBase();
virtual int init(QString* configureFilePath) = 0;
virtual int connectDevice() = 0;
protected:
int _dataBytesReceived;
ImageRawDataQueue* _queue;
};
#endif // DETECTORINTERFACE_H
2.工厂类:管理detector
#ifndef DETECTORFACTORYINTERFACE_H
#define DETECTORFACTORYINTERFACE_H
#include<QObject>
#include "detectorinterface.h"
class DetectorFactoryInterface
{
public:
virtual ~DetectorFactoryInterface() = default;
virtual QString modelName() = 0;
virtual DetectorBase* create(QString* configFile) = 0;
};
QT_BEGIN_NAMESPACE
#define DetectorFactoryInterfaceIID "com.security_machine.Telesound.DetectorFactoryInterface"
Q_DECLARE_INTERFACE(DetectorFactoryInterface, DetectorFactoryInterfaceIID)
QT_END_NAMESPACE
#endif // DETECTORFACTORYINTERFACE_H
解惑: 为什么要使用工厂类?
工厂方法是一种在工厂类中创建对象的设计模式,它通常用于处理对象的创建逻辑。工厂方法可以是非静态的,也可以是静态的。在这里,我将提供一个静态工厂方法的示例。
假设我们有一个简单的Shape类,它有一个子类Circle和Rectangle。我们可以创建一个静态工厂方法来根据给定的类型创建和返回相应的Shape对象。
#include <iostream>
#include <string>
#include <unordered_map>
// 基类 Shape
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
// 子类 Circle
class Circle : public Shape {
public:
void draw() override {
std::cout << "Inside Circle::draw()" << std::endl;
}
};
// 子类 Rectangle
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Inside Rectangle::draw()" << std::endl;
}
};
// 静态工厂方法类
class ShapeFactory {
public:
// 静态工厂方法
static Shape* getShape(const std::string& shapeType) {
if (shapeType == "CIRCLE") {
return new Circle();
} else if (shapeType == "RECTANGLE") {
return new Rectangle();
}
return nullptr;
}
};
int main() {
// 使用静态工厂方法创建对象
Shape* shape1 = ShapeFactory::getShape("CIRCLE");
Shape* shape2 = ShapeFactory::getShape("RECTANGLE");
if (shape1 != nullptr) {
shape1->draw();
delete shape1;
}
if (shape2 != nullptr) {
shape2->draw();
delete shape2;
}
return 0;
}
在这个例子中,ShapeFactory类包含了一个静态方法getShape,它根据传入的shapeType参数来创建并返回相应的Shape子类对象。这种方法的好处是,它将对象的创建逻辑集中在一个位置,使得代码更加模块化和易于维护。同时,它也提供了扩展性,允许在未来添加新的Shape子类而无需修改现有代码