Skip to main content
 首页 » 编程设计

python之从 .exe 中提取 .ico 并使用 PyQt 绘画的最佳方法

2025年05月04日10java哥

我正在寻找一种使用 Python 从 .exe 文件中提取图标的方法。我知道您可以使用 win32gui 的 ExtractIconEx 函数来获取 .exe 的图标,但这会返回一个 HIcon 资源句柄,这不好,因为我想使用 PyQt 绘制图标。

也是我看到的唯一一个使用 win32gui 的例子没有任何透明度,图标看起来也不平滑。

使用 Python 和 PyQt 执行此操作的最佳方法是什么?

--编辑--

感谢 Lukáš Lalinský 的帮助,这个问题现在已经解决了,这是最终代码,任何人都在寻求做与我类似的事情:

import sys 
import win32ui 
import win32gui 
from PyQt4 import QtCore 
from PyQt4 import QtGui 
 
class testWindow(QtGui.QMainWindow): 
    def __init__(self): 
        super(testWindow, self).__init__() 
        self.setGeometry(180.0, 130.0, 280.0, 400.0) 
        self.setMouseTracking(True) 
 
        large, small = win32gui.ExtractIconEx('C:\\Users\\Blank\\Apps\\Web Browsers\\Firefox\\Firefox.exe', 0) 
        win32gui.DestroyIcon(small[0]) 
 
        self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2) 
    def bitmapFromHIcon(self, hIcon): 
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) 
        hbmp = win32ui.CreateBitmap() 
        hbmp.CreateCompatibleBitmap(hdc, 32, 32) 
        hdc = hdc.CreateCompatibleDC() 
        hdc.SelectObject(hbmp) 
        hdc.DrawIcon((0, 0), hIcon) 
        hdc.DeleteDC() 
        return hbmp.GetHandle() 
    def paintEvent(self, event): 
        painter = QtGui.QPainter() 
        painter.begin(self) 
        painter.setRenderHint(QtGui.QPainter.Antialiasing) 
        painter.setPen(QtCore.Qt.NoPen) 
        painter.setBrush(QtGui.QBrush(QtGui.QColor(255.0, 255.0, 255.0, 255.0), QtCore.Qt.SolidPattern)) 
        painter.drawRect(QtCore.QRect(0.0, 0.0, 280.0, 400.0)) 
        painter.drawPixmap(QtCore.QRect(0.0, 0.0, 32.0, 32.0), self.pixmap) 
        painter.end() 
 
if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    mainWindow = testWindow() 
    mainWindow.show() 
    app.exec_() 

请您参考如下方法:

有一种方法可以从HBITMAP创建QPixmap,所以唯一的问题是如何将HICON转换为HBITMAP。这可以使用 GetIconInfo 来完成。

icons = win32gui.ExtractIconEx('C:/Program Files/Internet Explorer/iexplore.exe', 0, 10) 
info = win32gui.GetIconInfo(icons[0][0]) 
pixmap = QtGui.QPixmap.fromWinHBITMAP(info[4]) 
info[3].close() 
info[4].close() 
# call win32gui.DestroyIcon on all the icons returned by ExtractIconEx 

编辑: 此代码对抗锯齿和 alpha channel 没有帮助。您的新代码几乎是正确的,但您需要告诉 Qt 加载 alpha channel 。如果您更换:

self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0])) 

与:

self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2) 

它会做正确的事。 “魔法”数字 2 在技术上应该是 QtGui.QPixmap.Alpha 但出于某种原因 Qt 没有提供常量。