woboq/qmetaobject-rs

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

andrew-otiv opened this issue · 3 comments

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.

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.

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 {}