Qt 插件的制作

简介
插件是一种遵循一定规范的应用程序接口编写出来的程序,定位于开发实现应用软件平台不具备的功能的程序。
插件API
Qt提供了两种API用于创建插件:一种是高阶API,用于扩展Qt本身的功能,如自定义数据库驱动,图像格式,文本编码,自定义样式等;一种是低阶API,用于扩展Qt应用程序。
通过插件扩展应用程序功能
A、定义一个接口集(只有纯虚函数的类),用来与插件交流。
B、用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统。
C、应用程序中用QPluginLoader来加载插件。
D、用宏qobject_cast()来判断一个插件是否实现了接口。
创建插件
A、声明插件类,插件类继承自QObject和插件实现的接口。
B、用宏Q_INTERFACES()将插件接口告诉Qt元对象系统。
C、用宏Q_EXPORT_PLUGIN2()导出插件类。
D、用适当的.pro文件构建插件。

今天本来准备在网上找一下,看到很多博客就弄一点,扣扣搜搜生怕我学会了,要么就是要下载。不啰嗦直接进入主题。

第一步 创建工程
创建工程,选择“Other Project”->“Subdirs Project”,填写工程名称为MyPluginDemo,选择保存目录。
在这里插入图片描述
在这里插入图片描述
第二步****创建应用工程
在PluginApp工程上右键选择“New Subproject”菜单项,选择创建一个GUI应用,工程名称为MainAPP。

在这里插入图片描述
ui 界面就当做一个小的计算器
在这里插入图片描述
第三步 : 插件接口创建
在MainApp应用增加一个接口CalInterface.h。

#ifndef CALINTERFACE_H
#define CALINTERFACE_H

#include <QString>
#include <QtPlugin>

/*
    定义计算的接口类  里面的方法都是纯虚函数
*/
class CalInterface
{
public:
    virtual ~CalInterface(){}

    virtual bool check(QString type,int a,int b) = 0; //检验
    virtual int cal(QString type,int a,int b)=0;  //计算
};

//声明接口类 IID
#define CalInterface_iid "MyPlugins.CalInterface"

QT_BEGIN_NAMESPACE
    Q_DECLARE_INTERFACE(CalInterface,CalInterface_iid)
QT_END_NAMESPACE

#endif // CALINTERFACE_H

第四步 创建插件子工程
在MyPluginDemo工程上右键选择“New Subproject”菜单项,选择创建一个的Library的C++库。本质就是一个lib 库
在这里插入图片描述
类型选择Qt Plugin 名称为CalPlugin
在这里插入图片描述
第五步 接口实现类的创建
创建实现插件接口的实现类CalPluginClass由于基类没有是CalInterface 现在还没有导入所以选择还没有。后面可以更改
在这里插入图片描述
适当修改pro文件
在这里插入图片描述
第六步 接口类的实现
CalPluginClass 对接口类的实现
头文件


```cpp
#ifndef CALPLUGINCLASS_H
#define CALPLUGINCLASS_H

#include <QObject>
#include "calinterface.h"

class CalPluginClass : public QObject,public CalInterface
{
    Q_OBJECT

    Q_PLUGIN_METADATA(IID "MyPlugins.CalInterface")   //插件的数据信息
    Q_INTERFACES(CalInterface)    //接口类
public:
    CalPluginClass(QObject *parent = 0);
    //重写方法
    bool check(QString type,int a,int b)  override; //检验
    int cal(QString type,int a,int b) override;  //计算
};

#endif // CALPLUGINCLASS_H

源文件

#include "calpluginclass.h"
#include "qmath.h"

CalPluginClass::CalPluginClass(QObject *parent) :
    QObject(parent)
{
}

bool CalPluginClass::check(QString type, int a, int b)
{
    bool ret;
    Q_UNUSED(a);
    //除法分母不可以为0
    if(type=="除"){
        if(b==0){
            ret=false;
        }else{
            ret=true;
        }
    }else {
        ret=true;
    }

    return ret;
}

int CalPluginClass::cal(QString type, int a, int b)
{
    int sum;
    if(type=="加"){
        sum=a+b;
    }else if(type=="减"){
        sum=a-b;
    }else if(type=="乘"){
        sum=a*b;
    }else{
        sum=a/b;
    }
    return sum;
}

第七步 应用工程对插件的加载
mainwindow 头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "calinterface.h"
#include <QIntValidator>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    //加载插件
    bool loadPlugin();
private slots:
    void on_pushButton_clicked();
private:
    Ui::MainWindow *ui;
    CalInterface *m_interface;
};

#endif // MAINWINDOW_H

mainwindow 源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDir>
#include <QPluginLoader>
#include <QApplication>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //验证器
    QIntValidator *val=new QIntValidator(0,999,this);
    ui->lineEdit->setValidator(val);
    ui->lineEdit_2->setValidator(val);
    if (!loadPlugin())
    {
        QMessageBox::information(this, "Error", "Could not load the plugin");
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

//判断插件的是否存在
bool MainWindow::loadPlugin()
{
    bool ret = true;
    //获取当前应用程序所在路径
    QDir pluginsDir(qApp->applicationDirPath());
#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release"){
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS")
    {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#elif defined(Q_OS_LINUX)
    pluginsDir.cdUp();
#endif
    //切换到插件目录
    pluginsDir.cd("plugins");
    //遍历plugins目录下所有文件
    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));

        QObject *plugin = pluginLoader.instance();
        if (plugin)
        {
            //插件名称
            QString pluginName = plugin->metaObject()->className();
            //对插件初始化
            if(pluginName == "CalPluginClass")
            {
                m_interface = qobject_cast<CalInterface*>(plugin);
                if (m_interface)
                    ret =  true;
                break;
            }
            else
            {
                ret = false;
            }
        }
    }
    return ret;
}

void MainWindow::on_pushButton_clicked()
{
    int a=ui->lineEdit->text().trimmed().toInt();
    int b=ui->lineEdit_2->text().trimmed().toInt();
    QString type=ui->comboBox->currentText();
    bool ret=m_interface->check(type,a,b);
    if(ret){
        int sum=m_interface->cal(type,a,b);
        ui->label->setText(QString("%1").arg(sum));
    }else{
        ui->label->setText("除法分母不可以为零");
    }
}

看都看完了 点个赞再走呗!!!!嘻嘻!!

运行结果
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值