Лучший способ извлечь .ico из .exe и нарисовать с помощью PyQt?

StackOverflow https://stackoverflow.com/questions/1616342

  •  06-07-2019
  •  | 
  •  

Вопрос

Я ищу способ извлечь иконку из exe-файла с помощью Python.Я знаю, что вы можете использовать функцию ExtractIconEx win32gui для захвата значка .exe, но это возвращает дескриптор ресурса HIcon, который никуда не годится, потому что я хочу нарисовать значок с помощью PyQt.

Кроме того, единственный пример, который я видел с использованием win32gui, не имеет прозрачности, и значки не выглядят гладкими.

Каков был бы наилучший способ сделать это с помощью Python и PyQt?

--Редактировать--

Благодаря помощи Лукаша Лалинского эта проблема теперь решена, вот окончательный код, если кто-нибудь хочет сделать что-то подобное со мной:

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_()
Это было полезно?

Решение

Существует метод для создания QPixmap из HBITMAP, так что единственная проблема заключается в том, как преобразовать 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

Редактировать: Этот код не поможет со сглаживанием и альфа-каналом.Ваш новый код почти правильный, но вам нужно сказать Qt, чтобы он загрузил альфа-канал.Если вы замените:

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

с:

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

это будет правильно."Волшебное" число 2 технически это должно быть QtGui.QPixmap.Alpha но по какой-то причине Qt не предоставляет константу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top