Python中如何使用PyQt5获取exe文件中的图标

网上找到 pyqt4 的获取 exe 图标的方式是:得到 Bitmap 后通过 QtGui 里的 fromWinHBITMAP 方法将 bitmap 转换成透明背景的 QPixmap。但是 pyqt5 这样获取不了。是不是调用函数不对,求教。
Python中如何使用PyQt5获取exe文件中的图标

2 回复
import sys
import ctypes
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import Qt

def extract_icon_from_exe(exe_path, icon_index=0):
    """
    从EXE文件中提取图标
    
    参数:
        exe_path: EXE文件路径
        icon_index: 图标索引(默认0表示第一个图标)
    
    返回:
        QIcon对象或None
    """
    try:
        # 使用Windows API提取图标
        large_icons = ctypes.c_void_p()
        small_icons = ctypes.c_void_p()
        
        # 提取图标
        result = ctypes.windll.shell32.ExtractIconExW(
            exe_path,  # EXE文件路径
            icon_index,  # 图标索引
            ctypes.byref(large_icons),  # 大图标句柄
            ctypes.byref(small_icons),  # 小图标句柄
            1  # 提取数量
        )
        
        if result > 0 and large_icons:
            # 将图标句柄转换为QPixmap
            hicon = large_icons
            icon_pixmap = QPixmap.fromWinHICON(hicon)
            
            # 清理资源
            ctypes.windll.user32.DestroyIcon(hicon)
            if small_icons:
                ctypes.windll.user32.DestroyIcon(small_icons)
            
            return QIcon(icon_pixmap)
            
    except Exception as e:
        print(f"提取图标失败: {e}")
    
    return None

class IconViewer(QWidget):
    def __init__(self, exe_path):
        super().__init__()
        self.exe_path = exe_path
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle('EXE图标查看器')
        self.setGeometry(300, 300, 400, 300)
        
        layout = QVBoxLayout()
        
        # 提取并显示图标
        icon = extract_icon_from_exe(self.exe_path)
        
        if icon:
            # 创建标签显示图标
            icon_label = QLabel()
            pixmap = icon.pixmap(64, 64)  # 64x64大小
            icon_label.setPixmap(pixmap)
            icon_label.setAlignment(Qt.AlignCenter)
            
            # 创建标签显示文件路径
            path_label = QLabel(f"文件: {self.exe_path}")
            path_label.setAlignment(Qt.AlignCenter)
            
            layout.addWidget(icon_label)
            layout.addWidget(path_label)
            
            # 设置窗口图标
            self.setWindowIcon(icon)
        else:
            error_label = QLabel("无法提取图标")
            error_label.setAlignment(Qt.AlignCenter)
            layout.addWidget(error_label)
        
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    
    # 替换为你的EXE文件路径
    exe_file = r"C:\Windows\System32\notepad.exe"  # 示例:记事本程序
    
    viewer = IconViewer(exe_file)
    viewer.show()
    
    sys.exit(app.exec_())

核心原理是使用Windows API的ExtractIconEx函数提取EXE中的图标资源,然后通过PyQt5的fromWinHICON方法将Windows图标句柄转换为QPixmap。

主要步骤:

  1. 使用ctypes调用Windows API的ExtractIconExW函数
  2. 获取图标句柄后,用QPixmap.fromWinHICON()转换为Qt可用的格式
  3. 可以指定icon_index参数提取不同索引的图标

注意:这个方法只适用于Windows系统,因为依赖Windows API。如果是其他系统,需要不同的实现方式。

一句话总结:用Windows API提取图标句柄再转成Qt格式。


fromWinHBITMAP 在 Qt5 换名字了,这个函数还是有的,放在 WinExtras 里了。
----------------------------------
https://doc.qt.io/qt-5/qtwinextras-iconextractor-main-cpp.html
官方文档里有例子,不过是 C++写的,可以参考下。

回到顶部