2

Pythonを使用して.exeファイルからアイコンを抽出する方法を探しています。win32guiのExtractIconEx関数を使用して.exeのアイコンを取得できることは知っていますが、PyQtを使用してアイコンをペイントしたいので、これはHIconリソースハンドルを返します。

また、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_()
4

2 に答える 2

1

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は定数を提供しません。

于 2009-10-24T08:40:25.797 に答える
0

fromWinHBITMAP(PySide6などで)にアクセスできない場合は、を使用してアイコンを作成できますwin32gui.DrawIconEx

import win32ui
import win32gui
from PySide6 import QtGui, QtCore, QtWidgets

# Get the icons
icons = win32gui.ExtractIconEx('C:/Program Files/Internet Explorer/iexplore.exe', 0)
icon = icons[0][0]
width = height = 32

# Create DC and bitmap and make them compatible.
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, width, height)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)

# Draw the icon.
win32gui.DrawIconEx(hdc.GetHandleOutput(), 0, 0, icon, width, height, 0, None, 0x0003)

# Get the icon's bits and convert to a QtGui.QImage.
bitmapbits = hbmp.GetBitmapBits(True)
image = QtGui.QImage(bitmapbits, width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
    
# Write to and then load from a buffer to convert to PNG.
# This step is only necessary if you are displaying the image.
# QtWidgets.QLabel and similar have trouble displaying the current format.
buffer = QtCore.QBuffer()
buffer.SetOpenMode(QtCore.QIODevice.ReadWrite)
image.save(buffer, "PNG")
image.loadFromData(buffer.data(), "PNG")
    
# Create a QtGui.QPixmap from the QtGui.QImage.
pixmap = QtGui.Pixmap.fromImage(image)

# Destroy the icons.
for iconList in icons:
    for icon in iconList:
        win32gui.DestroyIcon(icon)

# Display the image.
display_label = QtWidgets.QLabel()
display_label.setPixmap(pixmap)
display_label.show()
于 2021-04-26T23:35:02.633 に答える