woboq / qmetaobject-rs

Integrate Qml and Rust by building the QMetaObject at compile time.
MIT License
620 stars 89 forks source link

Example Request: An example with more than one .qml file #296

Open andrew-otiv opened 11 months ago

andrew-otiv commented 11 months ago

None of the current examples currently show how to load more than one qml file, i.e. so additional types and forms can be declared in qml forms:

(base) andrew-otiv@evo:~/src/qmetaobject-rs$ find . -name "*.qml"
./qmetaobject/tests/qml/main.qml
./qmetaobject/tests/qml/Bar.qml
./examples/todos/main.qml
./examples/webengine/main.qml
./examples/graph/src/main.qml

I have tried many combinations of QmlEngine::load_file, QmlEngine::load_data, QmlEngine::load_data_as, and with data embedded using the qrc! macro, rust's standard include_bytes! macro.

If licensing doesn't get in the way, perhaps one of the main qt examples could be ported over to qmetaobject-rs? The coffee machine example in particular only contains about 10 lines of C++ boilerplate, and the rest is implemented in QML and shouldn't require porting.

Or perhaps the button layout in the todos example could be factored into a separate form? I will take a crack at that.

andrew-otiv commented 11 months ago

I looked closer at the todos example code and there are a lot of references to the Rust-declared type mixed into the layout. Refactoring it and fixing up all the callbacks would probably cost me 2 work days, and I'm still not confident what I'm trying to achieve is even possible. I'm just going follow the examples and give up on multiple .qml files and also using qtcreator for now.

ratijas commented 11 months ago

Hi,

In order to reuse components, they need to be registered with the engine at a specified import URI, if that's what you are after. Simply loading files into an engine would make an engine run that individual component in its root context, but won't register it in any way to allow other components to create it on demand.

Have you tried a combination of qrc! macro with resource registration call and properly set QML_IMPORT_PATH?

https://doc.qt.io/qt-6/qtqml-syntax-imports.html#qml-import-path

Although rarely used, it is also possible to bridge a function that registers module components from existing files, e.g.

QUrl resolveUrl(const QString &fileName) {
    return QUrl(QStringLiteral("qrc:/qt-project.org/imports/org/kde/kirigami/") + fileName);
};

void KirigamiPlugin::registerTypes(const char *uri)
{
    Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kirigami"));
    qmlRegisterType(componentUrl(QStringLiteral("Card.qml")), uri, 2, 4, "Card");
    // ...
}
import org.kde.kirigami as Kirigami

Kirigami.Card {}
andrew-otiv commented 11 months ago

I have not experimented with QML_IMPORT_PATH yet; I figured the qrc! macro was embedding the file in the binary with some loader magic that would make the QML_IMPORT_PATH unnecessary. It would be nice if the resulting binary could be moved without breaking.

Thanks for another response!

On Fri, Aug 18, 2023 at 1:17 PM ratijas @.***> wrote:

Hi,

In order to reuse components, they need to be registered with the engine at a specified import URI, if that's what you are after. Simply loading files into an engine would make an engine run that individual component in its root context, but won't register it in any way to allow other components to create it on demand.

Have you tried a combination of qrc! macro with resource registration call and properly set QML_IMPORT_PATH?

https://doc.qt.io/qt-6/qtqml-syntax-imports.html#qml-import-path

Although rarely used, it is also possible to bridge a function that registers module components from existing files, e.g.

QUrl resolveUrl(const QString &fileName) { return QUrl(QStringLiteral("qrc:/qt-project.org/imports/org/kde/kirigami/") + fileName); }; void KirigamiPlugin::registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kirigami")); qmlRegisterType(componentUrl(QStringLiteral("Card.qml")), uri, 2, 4, "Card"); // ... }

import org.kde.kirigami as Kirigami Kirigami.Card {}

— Reply to this email directly, view it on GitHub https://github.com/woboq/qmetaobject-rs/issues/296#issuecomment-1683764300, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAG5HZMEQZ4F7PO3ZWN7WQTXV5FMJANCNFSM6AAAAAA3VHRZG4 . You are receiving this because you authored the thread.Message ID: @.***>