检查Qt项目的 .ui 文件引用图标资源是否存在的脚本程序

一个项目中遇到一个问题,项目更新升级过程中,有一些模块比较长时间没有维护了,其中.ui文件引用的.qrc中的图标资源已经不存在了,就会导致程序运行的过程中无法显示图标。因为一个个排查太费时间,也容易漏,所有写了一个 Python 脚本来检查这个是不是有问题,将有问题的图标引用进行输出。

检查流程如下:

check
是<7.检查下一个>
8.没有iconset节点了
否<下一个>
1.迭代iconset节点
0.解析UI文件
2.读取resource属性
3.解析指向的qrc文件
4.读取normaloff标签节点
5.normaloff
指向的资源文件
在qrc文件中?
6.打印不存在的引用
9.结束
开始
输入要检查的目录
扫描目录
ui文件?

代码实现很简单,只是检查了引用的图标是否在qrc文件中,没有进一步检查图标文件是否存在,这是不完善的地方。因为Qt的代码中也可以通过setIcon(const QIcon& icon)接口来设置图标,所以这里也检查不到。要解决这个问题,需要检查所有代码文件。

代码如下:

import os
import xml.etree.ElementTree as ET


def get_iconset_path(ui_file, resource):
    ui_dir = os.path.dirname(ui_file)
    qrc_file = os.path.join(ui_dir, resource)
    return os.path.normpath(qrc_file)

def parse_qrc(qrc_file):
    # 使用 cache 缓存已经解析过的文件
    if hasattr(parse_qrc, 'cache') == False:
        setattr(parse_qrc, 'cache', dict())
    if qrc_file in parse_qrc.cache:
        return parse_qrc.cache[qrc_file]
    # 解析 qrc 文件
    try:
        tree = ET.parse(qrc_file)
    except IOError as err:
        print('\033[95m解析出错:{}\033[0m'.format(err))
        return []
    except BaseException as err:
        print('\033[95m解析异常:{}\033[0m'.format(err))
        return []
    
    root = tree.getroot()

    result = []
    for qresource in root.iter('qresource'):
        # 获取 prefix 属性
        prefix = qresource.get('prefix', '/')
        for file in qresource.iter('file'):
            rc_file = os.path.join(prefix, file.text).replace('\\', '/')
            # print(rc_file)
            result.append(':'+rc_file)
    # 存入缓存
    parse_qrc.cache[qrc_file] = result
    return result




def check_iconset(dir, ui_file):
    """ 对 ui 文件进行检查,输出图标不存在的部分
    :param dir: 遍历的目录,以便只输出文件名时候截取前面部分
    :param ui_file: 要检查的 ui 文件
    """
    print('check file:', os.path.relpath(ui_file, dir))
    tree = ET.parse(ui_file)
    root = tree.getroot()
    # 遍历所有iconset标签节点
    for iconset in root.iter('iconset'):
        # 获取resource属性并打印
        resource = iconset.get('resource')
        if resource is None:
            # print(iconset.text)
            continue
        qrc_file = get_iconset_path(ui_file, resource)
        # print('Resource:', qrc_file)
        result = parse_qrc(qrc_file)
        # print(result)

        # 判断节点下是否有normaloff标签节点
        normaloff = iconset.find('normaloff')
        if normaloff is not None:
            # 输出normaloff标签节点的内容
            # print('Normaloff:', normaloff.text)
            # 判断是否存在,如果不存在就输出
            if normaloff.text not in result:
                print('\033[31m\tnot found:{}\033[0m'.format(normaloff.text))


def walk_dir(directory):
    """ 对文件夹进行遍历处理
    """
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(".ui"):
                ui_file = os.path.join(root, file)
                check_iconset(directory, ui_file)


# 指定目录作为参数调用方法
directory = input("请输入目录路径:")
walk_dir(directory)

其他参考

posted @   乌合之众  阅读(83)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2018-09-19 抓取epsg.io的内容
clear
点击右上角即可分享
微信分享提示