Il modo migliore per estrarre .ico da .exe e dipingere con PyQt?
Domanda
Sto cercando un modo per estrarre un'icona da un file .exe usando Python. So che puoi usare la funzione ExtractIconEx di win32gui per afferrare l'icona di un file .exe ma questo restituisce un handle di risorse HIcon che non va bene perché voglio dipingere l'icona usando PyQt.
Anche l'unico esempio che ho visto usando win32gui non ha alcuna trasparenza e le icone non sembrano uniformi.
Quale sarebbe il modo migliore per farlo usando Python & amp; PyQt?
- Modifica -
Grazie all'aiuto di Luk & # 225; & # 353; Lalinsk & # 253; questo problema è ora risolto, ecco il codice finale: chiunque sta cercando di fare qualcosa di simile a 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_()
Soluzione
Esiste un metodo per creare QPixmap
da un HBITMAP
, quindi l'unico problema è come convertire HICON
in HBITMAP
. Questo può essere fatto 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
MODIFICA: questo codice non aiuta con l'antialias e il canale alfa. Il tuo nuovo codice è quasi corretto, ma devi dire a Qt di caricare il canale alfa. Se si sostituisce:
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]))
con:
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
farà la cosa giusta. La "magia" numero 2
dovrebbe essere tecnicamente QtGui.QPixmap.Alpha
ma per qualche ragione Qt non fornisce la costante.