首页 > 学院 > 开发设计 > 正文

Pyqt获取windows系统中已安装软件列表

2019-11-14 17:14:17
字体:
来源:转载
供稿:网友

开始之前的基础知识

 1. 获取软件列表

在Python的标准库中,_winreg可以操作Windows的注册表
获取已经安装的软件列表一般是读去windows的注册表: SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall
读取注册表循环出list
正则出 “DisplayIcon” 包含“exe” 或 “ico”

 1         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall", 0, _winreg.KEY_ALL_access) 2         for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1): 3             DisplayName = '' 4             DisplayIcon = '' 5             try: 6                  key_name_list =_winreg.EnumKey(key, i) 7                  each_key_path = "SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"+'//'+key_name_list 8                  each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS) 9                  DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")10                  DisplayName = DisplayName.encode('utf-8')11                  try:12                      DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")13                      DisplayIcon = DisplayIcon.encode('utf-8')14                  except WindowsError:15                      pass16                  #注册表中同时满足DisplayName 和 DisplayIcon17                  if DisplayName and DisplayIcon:18                      result = self.orderDict(str(i), DisplayName, DisplayIcon)19             except WindowsError:20                 pass

2.从exe中获取Icon资源

获取到了软件的列表,现在要把列表展示出来,肯定要查看软件的Icon了,所以要从已有的“DisplayIcon” 包含“exe”中读取exe的Icon
通过win32ui,win32gui 来获取exe中的Icon资源

 1 large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0) 2 self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2) 3 def bitmapFromHIcon(self, hIcon): 4         hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) 5         hbmp = win32ui.CreateBitmap() 6         hbmp.CreateCompatibleBitmap(hdc, 32, 32) 7         hdc = hdc.CreateCompatibleDC() 8         hdc.SelectObject(hbmp) 9         hdc.DrawIcon((0, 0), hIcon)10         hdc.DeleteDC()11         return hbmp.GetHandle()

3.QListWidget的Icon模型,与获取item值

在QListWidget 中setViewMode 设置查看的模型中为IconMode  ,才可以指定显示的Icon

1         self.contentsWidget = QtGui.QListWidget()2         self.contentsWidget.setViewMode(QtGui.QListView.IconMode)3         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小4         self.contentsWidget.setMovement(QtGui.QListView.Static)  #Listview不让列表拖动5         self.contentsWidget.setMaximumWidth(800)  # 最大宽度6         self.contentsWidget.setSpacing(15)  # 间距大小

需要获取QListWidget中item。 首先要在定义QlistWidgetItem的时候setData 值

Atem=QtGui.QListWidgetItem(self.contentsWidget)exeMenu=‘data_string’Atem.setData(QtCore.Qt.UserRole, exeMenu)

获取:

item = self.contentsWidget.currentItem()location = item.data(QtCore.Qt.UserRole)Obj= location.toPyObject()PRint(Obj)

4.打开exe文件或目录

打开文件和目录参考: http://www.VEVb.com/dcb3688/p/4463670.html

        if Obj and os.path.exists(Obj):  #文件or 目录存在            if os.path.isfile(Obj):                import win32process                try:                    win32process.CreateProcess(str(Obj), '',None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,win32process.STARTUPINFO())                except Exception, e:                    print(e)            else:                os.startfile(str(Obj))        else:  # 不存在的目录            QtGui.QMessageBox.warning(self, (u'提示'),(u'无法打开不存在的目录!'),QtGui.QMessageBox.Yes)

 

完整代码如下:

  1 # -*- coding: UTF8 -*-  2 from PyQt4 import QtCore, QtGui  3 import _winreg  4 import re, sys, os, rcc  5 import win32ui  6 import win32gui  7 reload(sys)  8 sys.setdefaultencoding("utf-8")  9 class ListDialog(QtGui.QDialog): 10     def __init__(self, parent=None): 11         super(ListDialog, self).__init__(parent) 12  13         self.contentsWidget = QtGui.QListWidget() 14         self.contentsWidget.setViewMode(QtGui.QListView.IconMode) 15         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小 16         self.contentsWidget.setMovement(QtGui.QListView.Static)  #Listview不让列表拖动 17         self.contentsWidget.setMaximumWidth(800)  # 最大宽度 18         self.contentsWidget.setSpacing(15)  # 间距大小 19  20         winrege= winregeditor() 21         self.numreg=winrege.getreg() 22         for key in self.numreg.keys(): 23             Atem=QtGui.QListWidgetItem(self.contentsWidget) 24             try:  # ico 来自exe 25                 large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0) 26                 exeMenu=self.numreg[key]['exe'] 27                 win32gui.DestroyIcon(small[0]) 28                 self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2) 29             except Exception,e:  #ico 来自 icon 30                 if self.numreg[key].has_key('icon') and os.path.isfile(self.numreg[key]['icon']):  # 判断ico文件是否存在 31                     self.pixmap = QtGui.QPixmap(self.numreg[key]['icon']) 32                     iconMenu = self.numreg[key]['icon'] 33                     split = iconMenu.split('//') 34                     exeMenu ='//'.join(split[:-1]) 35                 else:  # 不存在ico文件给定默认图标 36                     self.pixmap = ':default.png' 37                     exeMenu = '' 38  39             Atem.setIcon(QtGui.QIcon(self.pixmap)) 40             Atem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) 41             Atem.setTextAlignment(QtCore.Qt.AlignHCenter) 42             Atem.setData(QtCore.Qt.UserRole, exeMenu) 43             DisplayName=self.numreg[key]['DisplayName'].encode('utf-8') 44             Atem.setToolTip(u""+DisplayName)  # tip 显示 45             if len(DisplayName)>=6: 46                 DisplayName=DisplayName.decode('utf8')[0:6].encode('utf8')+'' 47             Atem.setText(u""+DisplayName) 48              49              50         horizontalLayout = QtGui.QHBoxLayout() 51         horizontalLayout.addWidget(self.contentsWidget) 52         mainLayout = QtGui.QVBoxLayout() 53         mainLayout.addLayout(horizontalLayout) 54         self.setLayout(mainLayout) 55         self.setWindowTitle(u'Pyqt 显示已安装软件列表') 56         self.setWindowIcon(QtGui.QIcon(':favicon.ico')) 57         self.resize(600, 300) 58         self.contentsWidget.itemDoubleClicked.connect(self.DoubleClicked)  #双击事件 59          60          61     # 当窗体大小改变后重新绘制窗体   重新排列Icon效果 62     def paintEvent(self,event): 63         mw = self.geometry() 64         width=mw.width()  # 获取窗体宽度 65         self.contentsWidget.setViewMode(QtGui.QListView.IconMode) 66         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小 67         self.contentsWidget.setMaximumWidth(width) 68         self.contentsWidget.setSpacing(12)  # 间距大小 69     # win32 获取exe 资源 70     def bitmapFromHIcon(self, hIcon): 71         hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) 72         hbmp = win32ui.CreateBitmap() 73         hbmp.CreateCompatibleBitmap(hdc, 32, 32) 74         hdc = hdc.CreateCompatibleDC() 75         hdc.SelectObject(hbmp) 76         hdc.DrawIcon((0, 0), hIcon) 77         hdc.DeleteDC() 78         return hbmp.GetHandle() 79     # 双击事件 80     def DoubleClicked(self): 81         item = self.contentsWidget.currentItem()   # 获取当前item   <PyQt4.QtGui.QListWidgetItem object at 0x01775E40> 82         location = item.data(QtCore.Qt.UserRole)    # 获取item里面的data  <PyQt4.QtCore.QVariant object at 0x018FD9B0> 83         Obj= location.toPyObject() 84         if Obj and os.path.exists(Obj):  #文件or 目录存在 85             if os.path.isfile(Obj): 86                 import win32process 87                 try: 88                     win32process.CreateProcess(str(Obj), '',None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,win32process.STARTUPINFO()) 89                 except Exception, e: 90                     print(e) 91             else: 92                 os.startfile(str(Obj)) 93  94         else:  # 不存在的目录 95             QtGui.QMessageBox.warning(self, (u'提示'),(u'无法打开不存在的目录!'),QtGui.QMessageBox.Yes) 96  97          98          99         100 # 注册表操作101 class winregeditor:102     dicList = {}103 104     def orderDict(self, numkey, DisplayName, DisplayIcon):105         self.dicList[numkey] = {'DisplayName': DisplayName, 'DisplayIcon': DisplayIcon}106         exeIcon = re.compile('.*exe')107         match = exeIcon.match(DisplayIcon)108         if match: #匹配到exe, 可直接打开109             self.dicList[numkey]['exe'] = match.group()110         else:  # 没有exe,Icon可为ico 文件111             self.dicList[numkey]['icon'] =DisplayIcon112         return self.dicList113 114 115     def getreg(self):116         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall", 0, _winreg.KEY_ALL_ACCESS)117         for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):118             DisplayName = ''119             DisplayIcon = ''120             try:121                  key_name_list =_winreg.EnumKey(key, i)122                  each_key_path = "SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"+'//'+key_name_list123                  each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)124                  DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")125                  DisplayName = DisplayName.encode('utf-8')126                  try:127                      DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")128                      DisplayIcon = DisplayIcon.encode('utf-8')129                  except WindowsError:130                      pass131                  #注册表中同时满足DisplayName 和 DisplayIcon132                  if DisplayName and DisplayIcon:133                      result = self.orderDict(str(i), DisplayName, DisplayIcon)134             except WindowsError:135                 pass136 137         return result138 139 140 141          142 if __name__ == '__main__':143     app = QtGui.Qapplication(sys.argv)144     dialog = ListDialog()145     dialog.show()146     sys.exit(app.exec_())

效果:

控制面板--软件删除:

QlistWidget软件列表效果:


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表