Qt 插件系统的使用和简单示例

本文介绍了如何在Qt环境中利用插件系统进行程序扩展。通过一个简单的EchoPlugin示例,展示了从配置、类实现到主窗口调用插件的全过程,帮助理解Qt插件与动态库的使用。

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

0. 前言

Qt 有自己的插件系统, 使用插件框架开发程序, 便于扩展和管理, 插件实际上是动态库, 个人理解是与动态库的区别是有一个插件管理器, 使用相同的调用约定.

 

1. 环境

Qt 4.8.7 + win10

 

2. 功能

这个demo的功能是发送一个Message字符串到插件的函数, 并返回显示
 

3.目录

源码路径: Github下载源码地址

E:PluginApp
│  list.txt
│  PluginApp.pro
│  PluginApp.pro.user
│  
├─EchoPlugin
│      echoplugin.cpp
│      echoplugin.h
│      EchoPlugin.pro
│      main.cpp
│      
└─MainWindow
        echointerface.h
        main.cpp
        MainWindow.pro
        widget.cpp
        widget.h

可以看到, 使用了子项目开发模式, PluginApp 内有两个子项目, EchoPlugin和MainWindow

EchoPlugin: 插件子项目, 生成dll插件

MainWindow: 主窗口 , 调用插件

 

4. 用法

先不说细节, 只讲大概的思路

EchoPlugin

<1> pro中插件的相应配置

<2> 创建插件类, 实现相关的方法

MainWindow

<1> 定义插件的调用头文件, 里面是插件类的声明, 都是虚方法, 用于在创建插件对象时重载

<2> 加载插件类并使用

 

5. 源码

上部分核心代码

MainWindow子项目

echointerface.h 声明插件虚方法的头文件

#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H

#include <QString>

class EchoInterface
{
public:
    virtual ~EchoInterface() {}
    virtual QString echo(const QString &message) = 0;
};

#define EchoInterface_lib "Example.Plugin.EchoInterface"

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_lib)
QT_END_NAMESPACE

#endif // ECHOINTERFACE_H

loadPlugin() 加载插件

bool Widget::loadPlugin()
{
    bool ret = true;
    //获取当前应用程序所在路径
    QDir pluginsDir(qApp->applicationDirPath());
    qDebug() << pluginsDir;

#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();
    }
#elif defined(Q_OS_LINUX)
    pluginsDir.cdUp();
#endif
    //切换到插件目录
    pluginsDir.cdUp();
    pluginsDir.cd("plugins");
    qDebug() << pluginsDir;

    //遍历plugins目录下所有文件
    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        qDebug() << fileName;
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));

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

sendEcho 使用插件方法

void Widget::sendEcho()
{
    QString text = echoInterface->echo(lineEdit->text());
    label->setText(text);
}

 

EchoPlugin 插件子项目

echointerface.h

#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H


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

class EchoPlugin : public QObject, public EchoInterface
{
    Q_OBJECT
    Q_INTERFACES(EchoInterface)
public:
    explicit EchoPlugin(QObject *parent = 0);
    QString echo(const QString &message);
};

#endif // ECHOPLUGIN_H

echointerface.cpp

#include "echoplugin.h"

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

QString EchoPlugin::echo(const QString &message)
{
    return message;
}

Q_EXPORT_PLUGIN2(EchoPlugin, EchoPlugin)

 

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值