Dimitris Dakopoulos
Dimitris Dakopoulos

Reputation: 713

Qt resources files with CMake and AUTORCC

Problem

Fail to set main window icon.

Notes:

Code

This is a minimized code of my project. Tree:

|- CMakeLists.txt
|- main_window.hpp
|- main_window.cpp
|- main.cpp
|- resources
   | - resources.qrc
   | - images
       | - logo.png

main_window.cpp

#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow();
};

#endif

main_window.cpp

#include "main_window.hpp"

MainWindow::MainWindow()
{
    // i tried ":/images.png", ":/resources/images/logo.png", ":/logo.png"
    setWindowIcon(QIcon(":images/logo.png"));    
}

main.cpp

#include <QApplication>
#include "main_window.hpp"

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

    app.setOrganizationName("Organization");
    app.setApplicationName("Application Example");
    MainWindow mainWin;
    mainWin.show();

    return app.exec();

}

CMakeLists.txt.

cmake_minimum_required(VERSION 3.1)

project(qt_project)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt4 4.6 REQUIRED)

set(QT_USE_QTGUI TRUE)
set(QT_USE_QTXML TRUE)

include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})

add_library(mylib main_window.cpp)
add_executable(qt_test main.cpp)

target_link_libraries(qt_test
    mylib
    ${QT_LIBRARIES}
)

resources/resources.qrc

<!DOCTYPE RCC><RCC version="1.0">
    <qresource>
        <file>images/logo.png</file>
    </qresource>
</RCC>

Edit

This is the generated qrc_resources.cxx

#include <QtCore/qglobal.h>

static const unsigned char qt_resource_data[] = {
  // /users/ddakop/dev/misc/qt/resources/images/logo.png
  // ... removed hex data
};

static const unsigned char qt_resource_name[] = {
  // images
  // ... removed hex data
    // logo.png
  // ... removed hex data
  
};

static const unsigned char qt_resource_struct[] = {
  // :
  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
  // :/images
  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
  // :/images/logo.png
  0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,

};

QT_BEGIN_NAMESPACE

extern Q_CORE_EXPORT bool qRegisterResourceData
    (int, const unsigned char *, const unsigned char *, const unsigned char *);

extern Q_CORE_EXPORT bool qUnregisterResourceData
    (int, const unsigned char *, const unsigned char *, const unsigned char *);

QT_END_NAMESPACE


int QT_MANGLE_NAMESPACE(qInitResources_resources)()
{
    QT_PREPEND_NAMESPACE(qRegisterResourceData)
        (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_resources))

int QT_MANGLE_NAMESPACE(qCleanupResources_resources)()
{
    QT_PREPEND_NAMESPACE(qUnregisterResourceData)
       (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    return 1;
}

Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_resources))

System

CentOS-5, Qt-4.8.6, CMake-3.2.1, gcc-4.8.2

Upvotes: 27

Views: 44194

Answers (3)

Yun
Yun

Reputation: 3812

The problem is that the resources file isn't a library and should therefore not be used as a parameter for add_library().

Since this question appears to be a go-to for problems with adding resources, I've written this answer to be a comprehensive overview of how to (correctly) add resources, with code examples and links to the documentation.

There are 3 ways to add resources to a Qt/CMake project:

1. Using qt_add_executable()

This requires enabling CMAKE_AUTORCC. This is the easiest option. E.g.:

set(CMAKE_AUTORCC ON)

# ...

add_executable(qt_test main.cpp resources/resources.qrc)

2. Using qt_add_resources() ("variable variant")

Here, qt_add_resources() is used to create source code from the resources in the .qrc file, and to add these to the other source files. E.g.:

find_package(Qt6 REQUIRED COMPONENTS Core)

# ...

set(SOURCES main.cpp)
qt_add_resources(SOURCES resources/resources.qrc)
qt_add_executable(qt_test ${SOURCES})

3. Using qt_add_resources() ("target variant")

This does not use a .qrc file. Instead, the resource files are added directly. This option provides the most control. E.g.:

find_package(Qt6 REQUIRED COMPONENTS Core)

# ...

add_executable(qt_test main.cpp)
qt_add_resources(qt_test
    PREFIX "/images"
    FILES logo.png
)

The qt_add_resources() command was introduced in Qt 5.15 and is still available in Qt 6 as part of the Core component. These do not require AUTORCC to be enabled. For versions older than Qt 5.15, use qt5_add_resources().
If versionless commands are disabled, use qt6_add_resources() instead.

Upvotes: -1

Tarod
Tarod

Reputation: 7170

I think you need to link qrc_resources generated file.

I suppose you know the next info:

http://www.cmake.org/cmake/help/latest/manual/cmake-qt.7.html

Where you can see the next line:

add_executable(myexe main.cpp resource_file.qrc)

More info:

http://www.cmake.org/cmake/help/latest/prop_tgt/AUTORCC.html

Upvotes: 41

Chris Walker
Chris Walker

Reputation: 121

I'm not sure if this is new or not, but I have figured out a way to add resources to libraries.

In my library's CMakeLists.txt I have the following:

list (APPEND RESOURCES library.qrc)
qt5_add_resources (RCC_SOURCES ${RESOURCES})

...

add_library(library ${RCC_SOURCES} ${SOURCES})

In the library, in one of my "main classes" (for me, this class was the first thing that gets created in the library and the last thing that gets destroyed), I did the following:

class libClass : public QMainWindow {
  Q_OBJECT

public:
  libClass() : QMainWindow(nullptr, 0) {
    Q_INIT_RESOURCE(library);
  }

  ~libClass() {
    Q_CLEANUP_RESOURCE(library);
  }
};

Upvotes: 12

Related Questions