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

开始之前的基础知识

 1. 获取软件列表

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

 1         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall", 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 = "SOFTWAREMicrosoftWindowsCurrentVersionUninstall"+'\'+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                      pass
16                  #注册表中同时满足DisplayName 和 DisplayIcon
17                  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.cnblogs.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'] =DisplayIcon
112         return self.dicList
113 
114 
115     def getreg(self):
116         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall", 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 = "SOFTWAREMicrosoftWindowsCurrentVersionUninstall"+'\'+key_name_list
123                  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                      pass
131                  #注册表中同时满足DisplayName 和 DisplayIcon
132                  if DisplayName and DisplayIcon:
133                      result = self.orderDict(str(i), DisplayName, DisplayIcon)
134             except WindowsError:
135                 pass
136 
137         return result
138 
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软件列表效果:

原文地址:https://www.cnblogs.com/dcb3688/p/4468770.html