qt 插件系统

参考文献1
参考 qt 官方示例 Echo Plugin Example
怎样用 Qt 写个插件?

新建库项目

qt 插件系统
选择chose进入下一下页面,类型选择Qt Plugin,输入一个名称

新建如下文件
qt 插件系统

首先需要一个虚接口 echointerface.h,在插件工程和要运行插件的工程中都要使用

#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H

#include <QObject>
#include <QString>

//! [0]
class EchoInterface
{
public:
    virtual ~EchoInterface() = default;
    virtual QString echo(const QString &message) = 0;
};


QT_BEGIN_NAMESPACE

#define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface"

Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
QT_END_NAMESPACE

//! [0]
#endif

Q_DECLARE_INTERFACE() 向 Qt 元对象系统注册一下我写的这个接口。
该宏的第一个参数是接口类的名字,第二个参数是 iid(相当于一个身份证信息,可以随便写个字符串)。

至此,我的程序给外界提供了个公共接口,并且为了 Qt 编程方便还向元对象系统注册了一下。以后所有的插件都通过这个接口来扩展 app 的功能,当然也可以写更多的接口供外界调用。

接下来是写插件,要继承这个接口
echoplugin.h


#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H

#include <QObject>
#include <QtPlugin>
#include "echointerface.h"

//! [0]
class EchoPlugin : public QObject, EchoInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "MyQtPlugin.json")
    Q_INTERFACES(EchoInterface)

public:
    QString echo(const QString &message) override;
};
//! [0]

#endif

echoplugin.cpp

#include "echoplugin.h"

//! [0]
QString EchoPlugin::echo(const QString &message)
{
    return message;
}
//! [0]

然后编译生成,我们需要
MyQtPlugin.dll MyQtPlugin.lib echointerface.h这三个文件

我们再新建一个工程 做一个界面
qt 插件系统
把刚才那三个文件复制到现在工程的目录下,把echointerface.h添加到工程里面(右键添加现有文件)
qt 插件系统
echowindow.h

#ifndef ECHOWINDOW_H
#define ECHOWINDOW_H

#include <QWidget>
#include "echointerface.h"

QT_BEGIN_NAMESPACE
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
namespace Ui { class echowindow; }
QT_END_NAMESPACE

class echowindow : public QWidget
{
    Q_OBJECT

public:
    echowindow();
    ~echowindow();

private slots:
    void sendEcho();

private:
    void createGUI();
    bool loadPlugin();

    EchoInterface *echoInterface;
    QLineEdit *lineEdit;
    QLabel *label;
    QPushButton *button;
    QGridLayout *layout;
};
#endif // ECHOWINDOW_H

echowindow.cpp

#include "echowindow.h"
#include "ui_echowindow.h"
#include "echowindow.h"

#include <QCoreApplication>
#include <QDir>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QPluginLoader>
#include <QPushButton>

//! [0]
echowindow::echowindow()
{
    createGUI();
    setLayout(layout);
    setWindowTitle("Echo Plugin Example");

    if (!loadPlugin()) {
        QMessageBox::information(this, "Error", "Could not load the plugin");
        lineEdit->setEnabled(false);
        button->setEnabled(false);
    }
}
//! [0]

//! [1]
void echowindow::sendEcho()
{
    QString text = echoInterface->echo(lineEdit->text());
    label->setText(text);
}
//! [1]

//! [2]
void echowindow::createGUI()
{
    lineEdit = new QLineEdit;
    label = new QLabel;
    label->setFrameStyle(QFrame::Box | QFrame::Plain);
    button = new QPushButton(tr("Send Message"));

    connect(lineEdit, &QLineEdit::editingFinished,
            this, &echowindow::sendEcho);
    connect(button, &QPushButton::clicked,
            this, &echowindow::sendEcho);

    layout = new QGridLayout;
    layout->addWidget(new QLabel(tr("Message:")), 0, 0);
    layout->addWidget(lineEdit, 0, 1);
    layout->addWidget(new QLabel(tr("Answer:")), 1, 0);
    layout->addWidget(label, 1, 1);
    layout->addWidget(button, 2, 1, Qt::AlignRight);
    layout->setSizeConstraint(QLayout::SetFixedSize);
}
//! [2]

//! [3]
bool echowindow::loadPlugin()
{
    QDir pluginsDir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
        pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS") {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#endif
    pluginsDir.cd("plugins");
    const QStringList entries = pluginsDir.entryList(QDir::Files);
    for (const QString &fileName : entries) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if (plugin) {
            echoInterface = qobject_cast<EchoInterface *>(plugin);
            if (echoInterface)
                return true;
            pluginLoader.unload();
        }
    }

    return false;
}

echowindow::~echowindow()
{

}


main.cpp

#include "echowindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    echowindow w;
    w.show();
    return a.exec();
}

上一篇:Android中activity的跳转 显示启动和隐式启动


下一篇:qt 中 ,在QMainWindow 手动添加layout,无法显示layout 中控件的解决办法。