从C ++加载QML插件

时间:2015-01-23 14:27:54

标签: c++ qt plugins qml

是否有可能从C ++加载QML插件,比如从QPluginLoader开始使用它来处理它的功能?在我的项目中,我有一个带有版本信息的qml插件,我想从C ++中读取它。

示例:

main() {
    // ...
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///ui/views/mainwindow.qml")));

    if (parser.isSet(verionsOption)) {
        QSharedPointer<QQmlExtensionPlugin> myPlugin = // load plugin
        std::cout << "Version of plugin: " << myPlugin->version() << std::endl;
    }

    return app.exec();
}

1 个答案:

答案 0 :(得分:3)

anwser是.. 。几个月后,我又能够回到这个任务。

所以,在qt源代码中我们可以看到QQmlExtensionPlugin。它实际上是一个qt插件(我们可以通过QPluginLoader打开) - QPlugin。在我看来,它应该列在Qt's plugin type list

为了能够在应用程序中打开qml插件,您的插件类必须实现一些接口,您将在应用程序中使用qobject_cast进行转换。在我的项目中,它看起来像:

#ifndef MYPLUGIN_H
#define MYPLUGIN_H

#include <QQmlExtensionPlugin>

class ExternalInterface
{
public:
    virtual const QString pluginVersion() const = 0;
    virtual const QString qxmppVersion() const = 0;
    virtual ~ExternalInterface() {}
};

Q_DECLARE_INTERFACE(ExternalInterface, "com.my.ExternalInterface")

class MyPlugin : public QQmlExtensionPlugin, public ExternalInterface
{
    Q_OBJECT
    Q_INTERFACES(ExternalInterface)
    Q_PLUGIN_METADATA(IID "com.MyPlugin")

    public:
        void registerTypes(const char *uri);
        void initializeEngine(QQmlEngine *engine, const char *uri);

        const QString pluginVersion() const final override;
        const QString qxmppVersion() const final override;
};

#endif // MYPLUGIN_H

接下来,在打开插件的应用程序的main.cpp中:

ExternalInterface* pluginVersion = nullptr;
#ifdef Q_OS_MACOS
    const QString fileSuffix = ".dylib";
#else
    const QString fileSuffix = ".so";
#endif
    QPluginLoader qmlPlugin(QApplication::applicationDirPath() + "../PlugIns/quick/libmyplugin" + fileSuffix);
    qmlPlugin.load();
    if (qmlPlugin.isLoaded()) {
        pluginVersion = qobject_cast<ExternalInterface*>(qmlPlugin.instance());
    } else {
            qmlPlugin.setFileName(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath) + "/fx/my/libmyplugin" + fileSuffix);
        qmlPlugin.unload();
        qmlPlugin.load();
        if (qmlPlugin.isLoaded()) {
            pluginVersion = qobject_cast<ExternalInterface*>(qmlPlugin.instance());
        } else {
            qDebug() << "ERROR while opening plugin: " << qmlPlugin.errorString();
        }
    }

    if (pluginVersion) {
        qDebug() << "Plugin: \n" << pluginVersion->pluginVersion() << "\n"
                 << pluginVersion->qxmppVersion() << "\n"
                 << "Location: " << qmlPlugin.fileName();
    } else {
        qDebug() << "Can't obtain version information from the plugin";
    }

最糟糕的是,您必须提供插件(共享库)的完整路径,并且您需要知道它在不同系统上的安装位置。