针对多工程情况下,Qwidget的ui文件的Stylesheet找不到图片的问题

基础:Qt存储图片路径:新建qic文件,然后将图片包含在内。注意路径是/:

情景再现:

📌单一工程:

首先,对于一个 C++ 工程 来说,必须要有一个程序入口函数,也就是 main() 函数

典型的最小工程结构如下:

cpp 复制代码
project1/
├── CMakeLists.txt
├── main.cpp
├── xx.h
└── xx.cpp

cmakelist.txt文件大致是这样的

cmake_minimum_required(VERSION 3.16)

project(project1 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 自动处理 Qt MOC/UIC/RCC(如果工程里用到 Qt)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

# 找 Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

# 工程源文件
set(PROJECT_SOURCES
    main.cpp
    xx.cpp
    xx.h
)

# 可执行文件 target
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(project1
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
    qt_finalize_executable(project1)
else()
    add_executable(project1 ${PROJECT_SOURCES})
endif()

target_link_libraries(project1 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

📌 多个可执行文件的情况

如果你需要在一个工程中生成多个可执行程序,就需要准备多个 main.cpp

cpp 复制代码
project_multi/
├── CMakeLists.txt
├── main1.cpp
├── main2.cpp
├── main3.cpp
├── xx.h
└── xx.cpp
CMakeLists.txt

cmakelist.txt文件大致是这样的:
cmake_minimum_required(VERSION 3.16)

project(project_multi VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

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

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

# 公共源文件(库代码)
set(COMMON_SOURCES
    xx.cpp
    xx.h
)

# =========================
# 可执行文件 main1
# =========================
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(main1 MANUAL_FINALIZATION main1.cpp ${COMMON_SOURCES})
    qt_finalize_executable(main1)
else()
    add_executable(main1 main1.cpp ${COMMON_SOURCES})
endif()
target_link_libraries(main1 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# =========================
# 可执行文件 main2
# =========================
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(main2 MANUAL_FINALIZATION main2.cpp ${COMMON_SOURCES})
    qt_finalize_executable(main2)
else()
    add_executable(main2 main2.cpp ${COMMON_SOURCES})
endif()
target_link_libraries(main2 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# =========================
# 可执行文件 main3
# =========================
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(main3 MANUAL_FINALIZATION main3.cpp ${COMMON_SOURCES})
    qt_finalize_executable(main3)
else()
    add_executable(main3 main3.cpp ${COMMON_SOURCES})
endif()
target_link_libraries(main3 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

CMakeLists.txt 中,通常会分别用 add_executable()qt_add_executable() 为不同的 mainX.cpp 生成不同的可执行文件。


📌 中间库(静态库 / 动态库)

在实际工程中,通常会把不包含 main() 的通用部分(.h.cpp、第三方库等)先编译成一个 中间库STATICSHARED library)。这样多个可执行文件就可以共用这部分逻辑,而不必重复编译。


📌 Qt 的特殊情况 ------ .qrc 资源文件

在 Qt 中,图片、QML、翻译文件等资源一般放到 .qrc(Qt Resource Collection)文件 中。

.qrc 会在编译时转换成一个 qrc_xxx.cpp,和源代码一起编译进最终可执行文件。

所以它必须要和 最终的可执行目标(含 main() 的 target) 一起参与编译,而不能单独放到中间库里,否则运行时会提示找不到资源。

例如:

cpp 复制代码
add_executable(${example_name} ${example_path})
target_sources(${example_name} PRIVATE
    pic/pic.qrc
    )

📌 QWidget 的问题:资源路径和 UI 文件分离

在 QWidget 工程中,如果你在 .ui 文件里直接写样式表,例如:

cpp 复制代码
background-image: url(:/pic/background.jpg);

或者直接手动拖拽设置.ui背景的时候

编译 .ui 时,这个资源路径并没有被验证,在中间库的时候并不能识别到路径。也就导致想想要点击设置.ui文件的stylesheet找不到图片路径

直到最后生成 可执行文件 时,Qt 的资源系统才会把 .qrc 打包进来,这个路径才会有效。

所以:这就是为什么 QWidget + 样式表 有时会出现 "多工程设计的时候图片路径找不到,但最终运行没问题" 的情况。


📌 QML 的不同之处

对于 QML 项目,资源路径的解析是运行时完成的,和 .ui 方式不同。

因此在 QML 工程中,一般不会遇到这种"中间库看不到资源"的问题。


📌 解决办法

要解决 QWidget 工程里资源路径丢失的问题,其实很简单:

👉 在中间库中也加入 .qrc 文件

这样,UI 设计文件和最终可执行文件都能看到相同的资源路径,就不会再出现 "设计时找不到,运行时才正常" 的问题。这个问题对于qml界面来说不是问题,但是对于想要使用qwidget设计的能够实时反馈来说确实很难受。

相关推荐
你才是向阳花1 天前
如何用Python实现飞机大战小游戏
开发语言·python·pygame
合作小小程序员小小店1 天前
web网页开发,在线%商城,电商,商品购买%系统demo,基于vscode,apache,html,css,jquery,php,mysql数据库
开发语言·前端·数据库·mysql·html·php·电商
星释1 天前
Rust 练习册 :Phone Number与电话号码处理
开发语言·机器学习·rust
one year.1 天前
Linux:线程同步与互斥
java·开发语言
一 乐1 天前
旅游|内蒙古景点旅游|基于Springboot+Vue的内蒙古景点旅游管理系统设计与实现(源码+数据库+文档)
开发语言·前端·数据库·vue.js·spring boot·后端·旅游
不爱编程的小九九1 天前
小九源码-springboot103-踏雪阁民宿订购平台
java·开发语言·spring boot
共享家95271 天前
LRU 缓存的设计与实现
开发语言·c++
2301_796512521 天前
Rust编程学习 - 问号运算符会return一个Result 类型,但是如何使用main函数中使用问号运算符
开发语言·学习·算法·rust
座山雕~1 天前
测试接口-----详细
开发语言·postman
小龙报1 天前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio