1

I have a sample project at https://github.com/jh3010-qt-questions/large_qrc

If I run the app from Qt Creator, I get a window which looks like the one below.

However, if I package the app with linuxdeployqt, only the bottom image on the window displays. It is loaded directly from disk. The top image is from a .qrc which should have been attached to the executable, but it does not appear.

My directory structure follows the recommendation from linuxdeployqt

$ tree usr
usr
├── bin
│   ├── image_assets
│   │   └── original_image_png
│   └── large_qrc
├── lib
└── share
    ├── applications
    │   └── large_qrc.desktop
    └── icons
        └── hicolor
            └── 256z256
                └── apps
                    └── large_qrc.png

I build the app image by doing:

linuxdeployqt usr/share/applications/large_qrc.desktop -appimage -qmake=/home/jamesh/Qt5.12.10/5.12.10/gcc_64/bin/qmake -qmldir=/home/jamesh/depot_qt/questions/large_qrc

I can double click on the resulting large_qrc-x86_64.AppImage executable from the Ubuntu GUI. The application launches successfully, but the top image does not show up.

What needs to be changed so QML Image can access the image in the .qrc?

A secondary question is whether or not there is a better way to handle the images in image_assets. It seems a bit odd to copy them into the bin folder, but perhaps that is a best practice in this situation.

If it matters, I am using Ubuntu 20.04

My project file is:

QT += quick

CONFIG += c++11

image_assets.files = $$PWD/image_assets
image_assets.path  = $$OUT_PWD
COPIES += image_assets

SOURCES += \
        main.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

qml.qrc

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
        <file>drawing.svg</file>
    </qresource>
</RCC>

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Column {
        Image {
            width: 200
            height: 200

            fillMode: Image.PreserveAspectFit

            source: "qrc:drawing.svg"
        }

        Image {

            width: 200
            height: 200

            fillMode: Image.PreserveAspectFit
            source: "file:///" + applicationDirPath + "/image_assets/original_image_png"
        }
    }
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    engine.rootContext()->setContextProperty( "applicationDirPath", QGuiApplication::applicationDirPath() );

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

large_qrc.desktop

[Desktop Entry]
Type=Application
Name=large_qrc
Comment=The best Qt Application Ever
Exec=large_qrc
Icon=large_qrc
Categories=Office;

This should be the output and is when I run the program from Qt Creator.

correct output

James Hudson
  • 844
  • 6
  • 19
  • Provably the Qt image plugins are missing. Notice that there are better solutions for packaging Qt applications than linuxdeployqt, please consider using https://github.com/linuxdeploy/ or https://appimage-builder.readthedocs.io/ – Alexis Apr 30 '21 at 16:38
  • Why would one select linuxdeploy over appimage-builder or vice-versa? – James Hudson Apr 30 '21 at 16:56
  • It would depend on how much control do you have over your dependencies and build process. If you can build your whole app on Ubuntu 16.04 (or 18.04 and not interested in having users with older version) you can go with linuxdeploy as it creates a smaller bundle. If you need to build your software on the very latest system then use appimage-builder. – Alexis May 03 '21 at 03:19

0 Answers0