Qt动态连接库 插件QPlugin库的创建与使用

 主要学习插件的生成和调用方法。

 问题:下图中是一个生成库的模块,其中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子类而无需修改现有代码

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老赵的博客

叮咚,你的赏钱已到账,嘿嘿嘿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值