¿La mejor manera de extraer .ico de .exe y pintar con PyQt?
Pregunta
Estoy buscando una forma de extraer un icono de un archivo .exe usando Python. Sé que puede usar la función ExtractIconEx de win32gui para tomar el ícono de un .exe, pero esto devuelve un identificador de recursos HIcon que no es bueno porque quiero pintar el ícono usando PyQt.
Además, el único ejemplo que he visto usando win32gui no tiene ninguna transparencia y los iconos no se ven suaves.
¿Cuál sería la mejor manera de hacer esto usando Python & amp; PyQt?
--Edit--
Gracias a la ayuda de Luk & # 225; & # 353; Lalinsk & # 253; este problema ya está resuelto, aquí está el código final si alguien está tratando de hacer algo similar a mí:
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_()
Solución
Hay un método para crear QPixmap
desde un HBITMAP
, por lo que el único problema es cómo convertir HICON
en HBITMAP . Esto se puede hacer usando
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
EDITAR: este código no ayudará con antialiasing y canal alfa. Su nuevo código es casi correcto, pero necesita decirle a Qt que cargue el canal alfa. Si reemplaza:
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]))
con:
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
hará lo correcto. La "magia" El número 2
debería ser técnicamente QtGui.QPixmap.Alpha
pero por alguna razón Qt no proporciona la constante.