如何将PyGtk的Gio.ThemedIcon转换为PyQt5可用的QIcon、QImage等格式?
解决方案
步骤1:将Gio.ThemedIcon转换为GdkPixbuf
Gtk提供了默认图标主题工具,可以直接根据Gio.ThemedIcon加载对应尺寸的像素缓冲区(GdkPixbuf),代码如下:
import gi gi.require_version('Gtk', '3.0') gi.require_version('GdkPixbuf', '2.0') from gi.repository import Gtk, Gio, GdkPixbuf # 你之前的业务代码 app_list = Gio.app_info_get_all_for_type('image/png') app = app_list[0] g_icon = app.get_icon() # 获取系统默认图标主题 icon_theme = Gtk.IconTheme.get_default() # 自定义图标尺寸,单位为像素 TARGET_ICON_SIZE = 48 try: # 查找图标并加载为GdkPixbuf icon_info = icon_theme.lookup_by_gicon( g_icon, TARGET_ICON_SIZE, Gtk.IconLookupFlags.USE_BUILTIN ) pixbuf = icon_info.load_icon() except Exception as e: # 加载失败时使用默认通用程序图标兜底 pixbuf = icon_theme.load_icon("application-x-executable", TARGET_ICON_SIZE, 0)
步骤2:转换为Qt可用的格式
拿到GdkPixbuf后,有两种常用方式可以转成QIcon/QImage:
方式1:直接从像素数据构造QImage(性能最高)
GdkPixbuf默认使用RGBA8888像素格式,可以直接读取像素数据构造QImage,无需额外编解码:
from PyQt5.QtGui import QImage, QPixmap, QIcon width = pixbuf.get_width() height = pixbuf.get_height() row_stride = pixbuf.get_rowstride() pixel_data = pixbuf.get_pixels() # 构造QImage q_img = QImage(pixel_data, width, height, row_stride, QImage.Format_RGBA8888) # 转QIcon q_icon = QIcon(QPixmap.fromImage(q_img))
方式2:导出为PNG字节流(通用性最强)
如果需要跨进程传输、存文件或者和其他图像处理库兼容,可以把Pixbuf导出为PNG格式的字节流:
import io from PIL import Image from PyQt5.QtGui import QImage def pixbuf_to_png_bytes(pixbuf): buffer = [] def write_chunk(chunk, user_data): user_data.append(chunk) return True pixbuf.save_to_callback(write_chunk, "png", {}, buffer) return b"".join(buffer) png_bytes = pixbuf_to_png_bytes(pixbuf) # 字节流转QImage q_img_from_bytes = QImage.fromData(png_bytes) # 字节流转PIL Image pil_img = Image.open(io.BytesIO(png_bytes))
注意事项
- 可以根据业务需求调整
TARGET_ICON_SIZE的数值,常用的桌面图标尺寸有16、24、32、48、64、128 - 如果是PySide环境,QImage的构造逻辑和上述代码完全一致,无需修改
- 代码已经做了兜底处理,找不到对应主题图标时会返回系统默认的通用程序图标,不会出现空指针报错
内容的提问来源于stack exchange,提问作者オパラ
相关产品推荐
相关产品推荐

