1
votes

I am importing 2 QML files that come with Qt Controls - ScrollBar.qml and Button.qml in my project. I pre-compile all .qml files that I wrote to reduce application launch time. Is there a way to pre-compile these 2 QML files that come as part of the package?

I tried to remove these files from the qml/QtQuick/Controls/ path and placed them in the same folder as my .qml files but it still failed to load. When I reference ScrollBar in my code, it always tries to load ScrollBar.qml from qml/QtQuick/Controls/ path.

Does any one know if it is possible to pre-compile these QMLs at all? If yes, has any one successfully done it?

Appreciate any help. Thank you.

1

1 Answers

1
votes

I'm assuming that you're referring to the Qt Quick Compiler as pre-compiling. The simplest way would just be to build the entire Qt Quick Controls module with the Qt Quick Compiler.

If you need to have it within your project, you could try adding an import that contains the Qt Quick Controls import. QQmlEngine::addImportPath() says:

The newly added path will be first in the importPathList().

That statement seems to imply that order matters, and the code confirms it:

QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local);

// Search local import paths for a matching version
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
for (const QString &qmldirPath : qmlDirPaths) {
    QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
    if (!absoluteFilePath.isEmpty()) {
        QString url;
        const QStringRef absolutePath = absoluteFilePath.leftRef(absoluteFilePath.lastIndexOf(Slash) + 1);
        if (absolutePath.at(0) == Colon)
            url = QLatin1String("qrc://") + absolutePath.mid(1);
        else
            url = QUrl::fromLocalFile(absolutePath.toString()).toString();

        QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
        cache->versionMajor = vmaj;
        cache->versionMinor = vmin;
        cache->qmldirFilePath = absoluteFilePath;
        cache->qmldirPathUrl = url;
        cache->next = cacheHead;
        database->qmldirCache.insert(uri, cache);

        *outQmldirFilePath = absoluteFilePath;
        *outQmldirPathUrl = url;

        return true;
    }
}

Your project structure might look something like this:

myproject/
    qml/
        main.qml
        QtQuick/
            Controls/
                Button.qml
                ScrollBar.qml
                qmldir

In main.cpp you'd set the path to the qml directory (note that the path will be different depending on whether you're doing an in-source build or a shadow build of your project, so you may want to use a resource file to simplify things):

engine.addImportPath("path/to/qml");

Note that the controls import other types. For example, Button uses the Settings singleton, which comes from the QtQuick.Controls.Private import, so you'd need to copy that into the qml directory, too. Settings loads a certain style for the button (ButtonStyle), which could be any of the styles in this folder, depending on which style is in use.

In short, you need to copy all of the potential dependencies of the QML files you're using.