Qt创建插件加载插件以及插件与主程序之间通信

1.Qt 创建插件

Qt创建插件加载插件以及插件与主程序之间通信_第1张图片

Qt创建插件加载插件以及插件与主程序之间通信_第2张图片

Qt创建插件加载插件以及插件与主程序之间通信_第3张图片

Qt创建插件加载插件以及插件与主程序之间通信_第4张图片

这几步就把一个插件创建好了,但是是个空的没有东西,我们加一个窗口类

form.h

#ifndef FORM_H
#define FORM_H

#include 

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = 0);
    ~Form();
public slots:

    void setLabelColor_slot(QPalette p);


signals:

    void labelColor_signal(QPalette p);

private slots:
    void on_red_btn_clicked();

    void on_green_btn_clicked();

private:
    Ui::Form *ui;
};

#endif // FORM_H

form.cpp

#include "form.h"
#include "ui_form.h"
#include 

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
}

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

void Form::setLabelColor_slot(QPalette p)
{
    ui->color_label->setPalette(p);
}

void Form::on_red_btn_clicked()
{
    QPalette palette;
    palette.setColor(QPalette::Background,QColor(255,0,0));

    ui->color_label->setAutoFillBackground(true);
    ui->color_label->setPalette(palette);

    emit  labelColor_signal(palette);
}

void Form::on_green_btn_clicked()
{
    QPalette palette;
    palette.setColor(QPalette::Background,QColor(0,255,0));

    ui->color_label->setAutoFillBackground(true);
    ui->color_label->setPalette(palette);

    emit  labelColor_signal(palette);
}

form.ui

Qt创建插件加载插件以及插件与主程序之间通信_第5张图片

两个颜色按钮,点击 改变label的背景颜色

void Form::setLabelColor_slot(QPalette p)
{
    ui->color_label->setPalette(p);
}

这个槽是等会在主程序与插件通信调用插件的槽.

这样直接编译就生成个dll
Qt创建插件加载插件以及插件与主程序之间通信_第6张图片

2.加载Qt插件

#include 
#include 


QWidget *loadPlugin(QString pluginPath)
{

    QPluginLoader loader(pluginPath);
    if(loader.load())
    {
        qDebug()<<"load ok";
    }
    else
    {
        qDebug()<<"load failed !";
        return NULL;
    }

    QObject* plugin = loader.instance();

    if(plugin)
    {
        QDesignerCustomWidgetInterface* interface =
                qobject_cast(plugin);

        if(interface)
        {
            QWidget* w = interface->createWidget(NULL);
            return w;
        }
    }
    else {
        qDebug()<<"loader.instance failed!";
        return NULL;
    }

}

loadPlugin 会返回一个 QWidget 的指针 指向的就是 插件的Form 窗口
因为我们插件 createWidget 返回的就是 form

Qt创建插件加载插件以及插件与主程序之间通信_第7张图片

与插件通信

当我们拿到 插件的form 实例化的对象,我们就可以用信号和槽了

    //信号槽
	QWidget* m_plugin =NULL;

    m_plugin = loadPlugin("D:\\testQtPlugins\\myplugind.dll");

    connect(this,SIGNAL(setLabelColor_signal(QPalette)),m_plugin,SLOT(setLabelColor_slot(QPalette)));

    connect(m_plugin,SIGNAL(labelColor_signal(QPalette)),this,SLOT(setLabelColor_slot(QPalette)));

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

signals:

    void setLabelColor_signal(QPalette p);
public slots:

    void setLabelColor_slot(QPalette p);




private slots:
    void on_red_btn_clicked();

    void on_green_btn_clicked();

    void on_loadPlugin_btn_clicked();

private:
    Ui::Widget *ui;

    QWidget* m_plugin;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include 
#include 
#include 

//加载插件

QWidget *loadPlugin(QString pluginPath)
{

    QPluginLoader loader(pluginPath);
    if(loader.load())
    {
        qDebug()<<"load ok";
    }
    else
    {
        qDebug()<<"load failed !";
        return NULL;
    }

    QObject* plugin = loader.instance();

    if(plugin)
    {
        QDesignerCustomWidgetInterface* interface =
                qobject_cast(plugin);

        if(interface)
        {
            QWidget* w = interface->createWidget(NULL);
            return w;
        }
    }
    else {
        qDebug()<<"loader.instance failed!";
        return NULL;
    }

}


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);




}

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

void Widget::setLabelColor_slot(QPalette p)
{
    ui->color_label->setPalette(p);
}




void Widget::on_red_btn_clicked()
{
    QPalette palette;
    palette.setColor(QPalette::Background,QColor(255,0,0));

    ui->color_label->setAutoFillBackground(true);
    ui->color_label->setPalette(palette);

    emit  setLabelColor_signal(palette);
}

void Widget::on_green_btn_clicked()
{
    QPalette palette;
    palette.setColor(QPalette::Background,QColor(0,255,0));

    ui->color_label->setAutoFillBackground(true);
    ui->color_label->setPalette(palette);

    emit  setLabelColor_signal(palette);
}

void Widget::on_loadPlugin_btn_clicked()
{
    //load plugin
    m_plugin = loadPlugin("D:\\testQtPlugins\\myplugind.dll");

    m_plugin->show();


    //信号槽

    connect(this,SIGNAL(setLabelColor_signal(QPalette)),m_plugin,SLOT(setLabelColor_slot(QPalette)));

    connect(m_plugin,SIGNAL(labelColor_signal(QPalette)),this,SLOT(setLabelColor_slot(QPalette)));


}

widget.ui

Qt创建插件加载插件以及插件与主程序之间通信_第8张图片

效果就是加载插件,主程序点击 红色按钮 主程序的label 和 插件的 label 都变为红色 ,点击 插件的绿色按钮,主程序和插件的label都变成绿色

Qt创建插件加载插件以及插件与主程序之间通信_第9张图片
Qt创建插件加载插件以及插件与主程序之间通信_第10张图片

!!!重要:

插件的编译环境要和加载插件的程序的编译环境 一摸一样 比如 插件用 Qt5.9编译的
那么加载插件的程序 也要用Qt5.9 用 Qt5.8编译就加载失败,并且 debug 的插件 对应debug的加载程序, release 对应 release.

你可能感兴趣的:(Qt)