是否可以创建 QML 组件库,其中所有 QML 文件都在二进制文件中,并且引擎仍然像 QtQuick 一样识别它?

问题描述 投票:0回答:1

是否可以创建 QML 组件库,其中所有 QML 文件都在二进制文件中,并且引擎仍然像 QtQuick 一样识别它?因此,所有 QML 文件都使用

*.a
文件捆绑到二进制文件中(例如
*.lib
*.qrc
...),用户可以像这样导入库:

import Foo // Foo is library name

Bar { // Bar is component name.
    // ...
}

就像您导入 QtQuick 一样,QML 引擎可以正常识别它,就像库有一个目录,其中有一个指向 QML 文件的

qmldir
文件。

我尝试将 QML 文件和

qmldir
文件放入 QRC 路径中并将其添加为 QML 引擎的导入路径,但这不起作用。另外,这不是 QML 引擎的错误,当我链接到库时,由于某种原因,我无法使用
QFile
读取文件(在测试应用程序的主函数中)。我对 QRC 的处理方式与普通应用程序的处理方式相同。

提示:我在 Qt 文档中发现了信息,您在发表评论之前一定要阅读它。

注1:我的Qt版本是Qt 6.6.1。 注2:我使用的是CMake,而不是qmake。

qt user-interface qml static-libraries
1个回答
0
投票

终于!我刚刚自己解决了这个问题...但请注意,该解决方案省略了

qmldir
文件或其他内容。首先,您必须为库和 QML 项目执行经典样板,其次,您必须为 QML 文件添加 QRC 文件,以将它们嵌入二进制文件中,第三,将此类添加到您的项目中:

// Foo.h

#ifndef FOO_H
#define FOO_H

#include <QQmlEngineExtensionPlugin>
#include <QQmlApplicationEngine>

class Foo : public QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)

public:

    void registerTypes(const char *uri) override;

private:

};

[[maybe_unused]] void setupFoo(); // Do not remove [[maybe_unused]].

#endif //FOO_H

// Foo.cpp

#include <QmlTypeAndRevisionsRegistration>

#include "Foo.h"

void Foo::registerTypes(const char *uri)
{
    // Register C++ types here:
    // qmlRegisterType<Foo>("Bar", 1, 0, "Bar"); // This is for the QML components that are made with C++. 

    // Register QML types here:
qmlRegisterType(QUrl("qrc:/Foo/QML/MyComponent.qml"), "Foo", 1, 0, "Bar"); // This is the real deal, the answer to my question, this is a specific overload for qmlRegisterType() that register QML types, effectively avoiding qmldir files and engine import paths, making the setup extremely easy to do.
}

[[maybe_unused]] void setupFoo() // Do not remove [[maybe_unused]].
{
    Q_INIT_RESOURCE(QML); //IMPORTANT: This is to initialize the resource explicitly because the linker might optimize and remove the auto generated code by RCC. This is so that the end user of the library can use the resources making Foo::registerTypes() work.
    Foo().registerTypes("Foo"); // I would not have been forced to call the constructor if Foo::registerTypes() was static. But since it is a virtual function and is not static I cannot change this fact.
}
© www.soinside.com 2019 - 2024. All rights reserved.