• 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软件列表效果:

  • 相关阅读:
    mysql同步之otter/canal环境搭建完整详细版
    Linux安装aria2
    mysql多源复制(多主一从)配置
    分布式调度框架TBSchedule使用方法
    hbase shell插入根据条件查询数据
    hive内部表&外部表介绍
    Canal( 增量数据订阅与消费 )的理解及应用
    tidb入门
    ES命令
    java8新特性
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4468770.html
Copyright © 2020-2023  润新知