如何在CMake项目中使用.rc文件为Windows Qt应用程序添加图标?

7

我正在尝试为我正在编写的应用程序添加应用程序图标,遵循https://doc.qt.io/qt-5/appicon.html中所述的步骤。

我使用Qt Desktop 5.15.2(64)6.1.2(64)来编译MinGWMSVC版本,并在Windows 1064位上进行编译。它们都没有出现错误或警告,但是图标没有显示出来。

我的CMakeFile.txt:

cmake_minimum_required(VERSION 3.14)

project(MyApp VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

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

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check https://doc.qt.io/qt/deployment-android.html for more information.
# They need to be set before the find_package(...) calls below.

if(ANDROID)
    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
#    if (ANDROID_ABI STREQUAL "armeabi-v7a")
#        set(ANDROID_EXTRA_LIBS
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
#    endif()
endif()

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick LinguistTools REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick LinguistTools REQUIRED)

set(TS_FILES _pt_BR.ts)

set(PROJECT_SOURCES
        main.cpp
        qml.qrc
        ${TS_FILES}
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/MyApp.rc")
    qt_add_executable(MyApp
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
        ${APP_ICON_RESOURCE_WINDOWS}
    )

    qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
    if(ANDROID)
        add_library(MyApp SHARED
            ${PROJECT_SOURCES}
        )
    elseif(WIN32)
        set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/windows/MyApp.rc")
        add_executable(MyApp
            ${PROJECT_SOURCES}
            ${APP_ICON_RESOURCE_WINDOWS}
        )

    else()
        add_executable(MyApp
          ${PROJECT_SOURCES}
        )
    endif()

    qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()

target_compile_definitions(MyApp
  PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(MyApp
  PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick)

set_target_properties(MyApp PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_import_qml_plugins(MyApp)
    qt_finalize_executable(MyApp)
endif()

MyApp.rc:

MyAppIcon ICON "MyApp.ico"

.ico文件包含一个256x256像素的32位RGBA图像。

就此事而言,在许多失败之后,我尝试使用qmake创建了一个测试项目,并在.pro文件中添加了图标:RC_ICONS = QtTest.ico,这起作用了(得到了正确的图标)。当我尝试使用RC_FILE = QtTest.rc时,它使用了默认图标,但没有任何警告或错误提示。

为了确保,我使用windres生成了.res文件,但是并没有成功。我修改了QtTestIco ICON "QtTest.ico"并重新生成了.res文件,结果仍然相同。

很遗憾,用CMakeList.txt替换.pro文件并使用RC_ICONS不是一个选项。

请问有人可以帮帮我吗?

提前致谢。


我遇到了同样的问题,Qt文档似乎没有指出如何明确指定图标,只是指向RC文件。QRC和RC是一样的吗? - jerrylogansquare
不,Windows中的.rc文件是描述生成的Windows二进制文件的某些详细信息的另一个文件。让我困扰的是,Qmake模板允许我们轻松添加图标,但Cmake的方式要复杂得多。 - Taupter
我不太了解cmake,但如果你的rc文件编码与#pragma code_page(#codepage#)定义不匹配,字符串可能会被错误解释。 - eddym
3个回答

4
为了添加Microsoft资源(RC)文件,您需要告诉CMake支持“RC”语言,启用Microsoft的RC语言。这将在检测到项目中具有*.rc扩展名的文件时启动资源编译器
以下是示例代码片段:
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
    enable_language("RC")
    set (WIN32_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/windows/MyApp.rc)
endif()

add_executable(MyApp WIN32
    ${PROJECT_SOURCES}
    ${WIN32_RESOURCES}
)

构建您的项目,Microsoft Explorer 将会看到您的图标。


1
对我来说,只需在add_executable调用中简单地添加.rc即可。 - Chnossos

1
假设您有以下文件(其中coremyapp仅作为示例):
core/
   CMakeLists.txt
   myapp.ico
   myapp.rc
   ...other dirs with your sources...

你的 myapp.rc 文件包含以下内容:

IDI_ICON1               ICON    DISCARDABLE     "myapp.ico"

假设您已安装了MS VC Build Tools并打开了x64 Native Tools命令提示符。您使用cmake等构建项目。这意味着您也有rc cmd程序。因此,在提示符中输入以下内容:
C:\Users\MyName\myapprepo\core>    rc  myapp.rc

然后你会得到一个二进制文件myapp.res:
core/
   CMakeLists.txt
   myapp.ico
   myapp.rc
   myapp.res

现在,您需要将此二进制文件链接到我们的lib/app中。在我的情况下,我称之为core库,我将其链接到可执行文件myapp。这并不重要。重点是您应该链接该文件:

# core/CMakeLists.txt

target_link_libraries(${CORE_LIBRARY_NAME} 
                      ${CMAKE_CURRENT_SOURCE_DIR}/myapp.res 
                      Qt5::Widgets)

MS VC编译器知道如何将res文件链接到您的lib/exe中,所以不用担心这个奇怪的实体。总的来说,整个过程与文档https://doc.qt.io/archives/qt-4.8/appicon.html中描述的完全一样:

如果您不使用qmake,则必须执行以下步骤:首先,在.rc文件上运行rc程序,然后使用生成的.res文件链接应用程序。

如果有任何问题,请在评论中提问。祝你好运!


0
  1. 创建一个rc文件并添加图标资源(resources.rc)

IDI_ICON1 ICON "main.ico"

main.ico应该与rc文件位于同一位置

  1. 在cmakefile中添加资源编译脚本

`add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resources.res COMMAND rc.exe ARGS /fo ${CMAKE_CURRENT_BINARY_DIR}/resources.res ${CMAKE_CURRENT_SOURCE_DIR}/resources.rc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/resources.rc WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )

  1. 在add_executable和target_link_libraries中添加资源文件

    ...

add_executable(<your_appname> ${PROJECT_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources.res)

...

target_link_libraries(<your_appname> PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/resources.res)

...

对我来说有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接