c++qtqmlqimage

QML image not showing up in window, no errors or warnings


I am able to load images through Qt's resource system, but they are not showing up in the window, without any warning or error messages.

According to the documentation, getting an image to show should be as simple as

Image {
    source: "pics/qtlogo.png"
}

For reproducibility, I will provide a minimal example in full: A CPP file, QML file, CMake config and the resource file.

// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QIcon>

int
main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
        &app, []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    
    app.setWindowIcon(QIcon(":/images/test.png"));
    engine.loadFromModule("qqt", "Main");

    return app.exec();
}
// Main.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts

Window {
    width: 800
    height: 480
    visible: true
    
    title: qsTr("QtQuick testing")
    
    GridLayout {
        anchors.fill: parent
        columns: 3
        
        RowLayout {
            spacing: 0

            Layout.column: 0
            
            Switch {
            }
            
            Image {
                source: ":/images/test.png"
                width: 48
                height: 48
            }
        }
    }    
}
cmake_minimum_required(VERSION 3.16)

project(qqt VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.5 REQUIRED COMPONENTS Quick)

qt_standard_project_setup(REQUIRES 6.5)

qt_add_executable(appqqt
    main.cpp
)

qt_add_qml_module(appqqt
    URI qqt
    VERSION 1.0
    QML_FILES Main.qml
    RESOURCES resources.qrc
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appqqt PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appqqt
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(appqqt
    PRIVATE Qt6::Quick
)

include(GNUInstallDirs)
install(TARGETS appqqt
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
<RCC>
    <qresource prefix="/images">
        <file>test.png</file>
        <file>test2.png</file>
    </qresource>
</RCC>

Application's screenshot:

App screenshot

The switch button shows up fine, but the image does not.

The image has transparency, but I have also tested images with no transparency with the same result.

As you can see from the cpp file, I have tried using the same image as the window icon, and this works fine. So the resources are being loaded correctly.

I also tried proving a URL to an image online in the QML code, and that actually worked, so I suspect the QML engine is not able to properly read the resource data.


Solution

  • It turns out that in QML, files from the resource system needs to have qrc:/ prefixed to paths.

    I've used Qt Widgets before, so I assumed I could use the same prefix of just :/, but this is not the case.

    So the fix was to change the Image to the following:

    Image {
        source: "qrc:/images/test.png"
    }