أفضل طريقة لاستخراج .ico من .exe والطلاء باستخدام PyQt؟
سؤال
أنا أبحث عن طريقة لاستخراج رمز من ملف .exe باستخدام بايثون.أعلم أنه يمكنك استخدام وظيفة ExtractIconEx الخاصة بـ win32gui للحصول على أيقونة ملف exe. لكن هذا يُرجع مقبض مورد HIcon وهو أمر غير جيد لأنني أريد رسم الأيقونة باستخدام PyQt.
كما أن المثال الوحيد الذي رأيته باستخدام 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_()
المحلول
هناك طريقة لإنشاء 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 الثابت.