Best way to extract .ico from .exe and draw with PyQt?

I'm looking for a way to extract an icon from an .exe file using Python. I know you can use the win32gui ExtractIconEx function to grab the .exe icon, but this returns a HIcon resource handle, which is not appropriate because I want to draw the icon using PyQt.

Also the only example I've seen using win32gui has no transparency and the icons don't look smooth.

What would be the best way to do this with Python and PyQt?

- Edit -

Thanks to the help of Lukasz Lalinski, this problem has now been solved, here is the final code: someone wants to do something similar to me:

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_()

      

+2


source to share


1 answer


There is a way to create QPixmap

from HBITMAP

, so the only problem is converting HICON

to HBITMAP

. This can be done using 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

      

EDIT: This code won't help with anti-aliasing and alpha channel. Your new code is almost correct, but you need to tell Qt to load the alpha channel. If you replace:

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

      



from:

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

      

it will go right. The "magic" number 2

should technically be QtGui.QPixmap.Alpha

, but for some reason Qt doesn't provide a constant.

+1


source







All Articles