Как создать разделяемую библиотеку в QT/QML

У меня есть 4 файла qml и один файл main.cpp для загрузки файла qml. Могу ли я создать 1 файл dll для этих 4 файлов qml. И использовать его в другом приложении, если да, то как это сделать.


person jay    schedule 05.12.2016    source источник
comment
почему вы хотите это сделать? если это только файлы qml, просто скопируйте файлы qml в другое приложение. Сделанный.   -  person MrBlueSky    schedule 05.12.2016
comment
@MrBlueSky В некоторых случаях вы бы не хотели, чтобы необработанный QML (исходный код) был доступен конечному пользователю.   -  person Rich von Lehe    schedule 24.03.2020


Ответы (2)


Как уже было сказано, нет необходимости встраивать файлы qml только в библиотеку. Но, конечно, вы имеете право делать все, что хотите, даже это. Я знаю как минимум 2 способа сделать это:

<сильный>1. Создать двоичный файл ресурсов
Подготовить файл ресурсов, содержащий файлы qml, а затем скомпилировать его:

rcc -binary plugin.qrc -o plugin.rcc

Теперь вы можете включить этот файл в свое приложение:

QResource::registerResource("plugin.rcc");

и используйте его как обычный файл qrc:

QResource::registerResource(qApp->applicationDirPath() + "/plugin.rcc");
QQuickView *view = new QQuickView();
view->setSource(QUrl("qrc:/qml/myfile.qml"));

Здесь qml/ — это префикс в файле ресурсов.

<сильный>2. Общая библиотека
Другой способ — создать общую библиотеку, содержащую тот же файл ресурсов. Например, разделяемая библиотека вашего плагина реализует следующий интерфейс:

interface.h

#ifndef PLUGIN_INTERFACE_H
#define PLUGIN_INTERFACE_H

#include <QString>
#include <QObject>

class PluginInterface
{
public:
    virtual ~PluginInterface() {}
    virtual QByteArray getQML(const QString &name) = 0;
};

#define PluginInterface_iid "org.qt-project.PluginInterface"

Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)

#endif

и его реализация:

QByteArray PluginImpl::getQML(const QString &name)
{
    QFile file(":/qml/" + name);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return QByteArray();
    return file.readAll();
}

Теперь в вашем приложении вы загружаете свой плагин и получаете его ресурс в виде строки:

QDir pluginsDir(qApp->applicationDirPath());
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath("plugin.dll"));
QObject *plugin = pluginLoader.instance();
if (plugin) {
    PluginInterface *pluginInstance = qobject_cast<PluginInterface *>(plugin);
    if (pluginInstance) {
        QByteArray content = pluginInstance->getQML("file1.qml");
        QQuickView *view = new QQuickView();
        QQmlComponent component(view->engine());
        component.setData(content, QUrl());
        QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create());
        childItem->setParentItem(view->contentItem());

        QWidget *container = QWidget::createWindowContainer(view);
        container->setFocusPolicy(Qt::TabFocus);
        ui->verticalLayout->addWidget(container);
    }
}

Но обратите внимание, что при развертывании приложения вам в любом случае придется скопировать все системные файлы qml, такие как #QTPATH/qml/QtQml, #QTPATH/qml/QtQuick.2, #QTPATH/qml/QtQuick.2 и т. д.< /эм>

Ссылки:

person folibis    schedule 06.12.2016
comment
При развертывании инструмента развертывания правильно распознаются зависимости как от Win, так и от MacOS, если используется параметр `qmldir`. Если бы я был вами, я бы добавил это. Кстати хороший ответ. - person BaCaRoZzo; 07.12.2016

Ознакомьтесь с документацией для модулей QML.

Существуют варианты для модулей только для QML, только для C++ и смешанного режима.

person Kevin Krammer    schedule 05.12.2016