从C ++加载QML插件 [英] QML Plugin load from C++

查看:175
本文介绍了从C ++加载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();
}

解决方案

答案是.. .几个月后,我又重新回到了这个任务.

因此,在qt源代码中,我们可以看到QQmlExtensionPlugin.它实际上是一个qt插件(我们可以通过QPluginLoader打开)-QPlugin.我认为应该在 Qt的插件类型列表中列出.

要能够在应用程序中打开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";
    }

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

Is it possible to load QML plugin from C++, say, from QPluginLoader to work with it's functions? In my project, I have a qml plugin with a version information in it and I want to read it from C++.

Example:

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();
}

解决方案

The anwser is.. yes. After few months I was able to get to this task back again.

So, in the qt source code we can see what QQmlExtensionPlugin. It is really a qt plugin (which we are able to open through QPluginLoader) - QPlugin. In my opinion it should be listed in Qt's plugin type list.

To be able to open your qml plugin in the application your plugin class must implement some interface to which you will cast with qobject_cast in the application. In my project it looks like:

#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

Next, in main.cpp of the application which opens the plugin:

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";
    }

The worst thing here is that you must provide full path to the plugin (shared library) and you need to know where it installs on different systems.

这篇关于从C ++加载QML插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆