You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用.qrc文件让QUiLoader加载的UI正常显示图标?

解决PySide5加载.ui文件时本地图标不显示问题(无需.qrc文件)

使用Qt Creator为Python项目制作.ui文件,仅用它做UI编辑,未用其管理整个项目。通过本地文件路径(未用.qrc)添加的图标在Qt Creator中显示正常,但用PySide5.15.2的QUiLoader加载后图标无法显示。

加载代码:

loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_path)
ui_file.open(QtCore.QFile.ReadOnly)
form = loader.load(ui_file)
ui_file.close()

.ui文件中图标相关XML片段:

...
<property name="icon">
 <iconset>
  <normaloff>../../resources/icons/list-add.svg</normaloff>../../resources/icons/list-add.svg</iconset>
</property>
...

原因分析

Qt Creator会基于项目根目录解析图标相对路径,但QUiLoader加载时,默认以Python进程的当前工作目录查找文件,且不会自动将.ui中的路径转换为可识别的本地文件图标,导致图标加载失败。

解决方案(无需.qrc及构建步骤)

方法1:加载UI后手动为控件设置图标

适合图标数量较少的场景,直接通过绝对路径构造QIcon并赋值给控件:

from PySide5 import QtUiTools, QtCore, QtGui, QtWidgets

loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_path)
ui_file.open(QtCore.QFile.ReadOnly)
form = loader.load(ui_file)
ui_file.close()

# 基于UI文件所在目录构造图标绝对路径
ui_dir = QtCore.QFileInfo(ui_path).absoluteDir()
abs_icon_path = ui_dir.filePath("../../resources/icons/list-add.svg")
# 替换为实际控件名称
form.pushButton.setIcon(QtGui.QIcon(abs_icon_path))

方法2:自定义QUiLoader自动处理图标

适合多图标场景,重写QUiLoader的createWidget方法,自动为控件设置正确路径的图标:

from PySide5 import QtUiTools, QtCore, QtGui, QtWidgets

class CustomUiLoader(QtUiTools.QUiLoader):
    def __init__(self, ui_path, parent=None):
        super().__init__(parent)
        self.ui_dir = QtCore.QFileInfo(ui_path).absoluteDir()

    def createWidget(self, className, parent=None, name=""):
        widget = super().createWidget(className, parent, name)
        # 针对按钮等带icon属性的控件做处理
        if isinstance(widget, QtWidgets.QAbstractButton):
            # 从.ui文件的相对路径构造绝对路径
            icon_rel_path = "../../resources/icons/list-add.svg"
            abs_icon_path = self.ui_dir.filePath(icon_rel_path)
            widget.setIcon(QtGui.QIcon(abs_icon_path))
        return widget

# 使用自定义加载器加载UI
loader = CustomUiLoader(ui_path)
ui_file = QtCore.QFile(ui_path)
ui_file.open(QtCore.QFile.ReadOnly)
form = loader.load(ui_file)
ui_file.close()

注:如果存在多个不同路径的图标,可以解析.ui文件的XML提取路径,或维护一个路径映射表适配所有图标。

方法3:切换Python进程工作目录到项目根目录

让QUiLoader的路径解析逻辑和Qt Creator一致,直接切换工作目录:

import os
from PySide5 import QtUiTools, QtCore

# 计算项目根目录(示例:UI文件在src/ui下,根目录为UI目录往上两级)
ui_abs_path = os.path.abspath(ui_path)
project_root = os.path.dirname(os.path.dirname(os.path.dirname(ui_abs_path)))
# 切换工作目录到项目根
os.chdir(project_root)

# 加载UI文件
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_abs_path)
ui_file.open(QtCore.QFile.ReadOnly)
form = loader.load(ui_file)
ui_file.close()

注意:切换工作目录会影响程序中其他文件路径的解析,需确保其他文件操作也适配此目录。

内容的提问来源于stack exchange,提问作者knipknap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:43:13