开始之前的基础知识

1. 获取软件列表

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

         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
DisplayName = ''
DisplayIcon = ''
try:
key_name_list =_winreg.EnumKey(key, i)
each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
DisplayName = DisplayName.encode('utf-8')
try:
DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
DisplayIcon = DisplayIcon.encode('utf-8')
except WindowsError:
pass
#注册表中同时满足DisplayName 和 DisplayIcon
if DisplayName and DisplayIcon:
result = self.orderDict(str(i), DisplayName, DisplayIcon)
except WindowsError:
pass

2.从exe中获取Icon资源

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

 large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 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()

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

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

         self.contentsWidget = QtGui.QListWidget()
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMovement(QtGui.QListView.Static) #Listview不让列表拖动
self.contentsWidget.setMaximumWidth(800) # 最大宽度
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)

完整代码如下:

 # -*- coding: UTF8 -*-
from PyQt4 import QtCore, QtGui
import _winreg
import re, sys, os, rcc
import win32ui
import win32gui
reload(sys)
sys.setdefaultencoding("utf-8")
class ListDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(ListDialog, self).__init__(parent) self.contentsWidget = QtGui.QListWidget()
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMovement(QtGui.QListView.Static) #Listview不让列表拖动
self.contentsWidget.setMaximumWidth(800) # 最大宽度
self.contentsWidget.setSpacing(15) # 间距大小 winrege= winregeditor()
self.numreg=winrege.getreg()
for key in self.numreg.keys():
Atem=QtGui.QListWidgetItem(self.contentsWidget)
try: # ico 来自exe
large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0)
exeMenu=self.numreg[key]['exe']
win32gui.DestroyIcon(small[0])
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
except Exception,e: #ico 来自 icon
if self.numreg[key].has_key('icon') and os.path.isfile(self.numreg[key]['icon']): # 判断ico文件是否存在
self.pixmap = QtGui.QPixmap(self.numreg[key]['icon'])
iconMenu = self.numreg[key]['icon']
split = iconMenu.split('\\')
exeMenu ='\\'.join(split[:-1])
else: # 不存在ico文件给定默认图标
self.pixmap = ':default.png'
exeMenu = '' Atem.setIcon(QtGui.QIcon(self.pixmap))
Atem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
Atem.setTextAlignment(QtCore.Qt.AlignHCenter)
Atem.setData(QtCore.Qt.UserRole, exeMenu)
DisplayName=self.numreg[key]['DisplayName'].encode('utf-8')
Atem.setToolTip(u""+DisplayName) # tip 显示
if len(DisplayName)>=6:
DisplayName=DisplayName.decode('utf8')[0:6].encode('utf8')+'…'
Atem.setText(u""+DisplayName) horizontalLayout = QtGui.QHBoxLayout()
horizontalLayout.addWidget(self.contentsWidget)
mainLayout = QtGui.QVBoxLayout()
mainLayout.addLayout(horizontalLayout)
self.setLayout(mainLayout)
self.setWindowTitle(u'Pyqt 显示已安装软件列表')
self.setWindowIcon(QtGui.QIcon(':favicon.ico'))
self.resize(600, 300)
self.contentsWidget.itemDoubleClicked.connect(self.DoubleClicked) #双击事件 # 当窗体大小改变后重新绘制窗体 重新排列Icon效果
def paintEvent(self,event):
mw = self.geometry()
width=mw.width() # 获取窗体宽度
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMaximumWidth(width)
self.contentsWidget.setSpacing(12) # 间距大小
# win32 获取exe 资源
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 DoubleClicked(self):
item = self.contentsWidget.currentItem() # 获取当前item <PyQt4.QtGui.QListWidgetItem object at 0x01775E40>
location = item.data(QtCore.Qt.UserRole) # 获取item里面的data <PyQt4.QtCore.QVariant object at 0x018FD9B0>
Obj= location.toPyObject()
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) # 注册表操作
class winregeditor:
dicList = {} def orderDict(self, numkey, DisplayName, DisplayIcon):
self.dicList[numkey] = {'DisplayName': DisplayName, 'DisplayIcon': DisplayIcon}
exeIcon = re.compile('.*exe')
match = exeIcon.match(DisplayIcon)
if match: #匹配到exe, 可直接打开
self.dicList[numkey]['exe'] = match.group()
else: # 没有exe,Icon可为ico 文件
self.dicList[numkey]['icon'] =DisplayIcon
return self.dicList def getreg(self):
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
DisplayName = ''
DisplayIcon = ''
try:
key_name_list =_winreg.EnumKey(key, i)
each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
DisplayName = DisplayName.encode('utf-8')
try:
DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
DisplayIcon = DisplayIcon.encode('utf-8')
except WindowsError:
pass
#注册表中同时满足DisplayName 和 DisplayIcon
if DisplayName and DisplayIcon:
result = self.orderDict(str(i), DisplayName, DisplayIcon)
except WindowsError:
pass return result if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog = ListDialog()
dialog.show()
sys.exit(app.exec_())

效果:

控制面板--软件删除:

QlistWidget软件列表效果:

Pyqt 获取windows系统中已安装软件列表的更多相关文章

  1. 获取Windows系统中的所有可用和在用串口

    目的:获取Windows系统中的所有可用和在用串口 方法:注册表查询法 优点:简单.实用.快速.无遗漏,无多余结果. 说明:另外还有8种方法可以枚举串口,但都不如此法. 代码和详细注释如下: //-- ...

  2. Windows系统中 JDK安装及环境配置

    需要安装jdk的第一步就是先去官网下载好JDK,选择需要的版本. Windows系统 1.将下载好的压缩包解压,点击解压得到的jdk执行文件开始安装.在安装过程中会弹出两个安装,一个是jdk,一个是j ...

  3. 二进制程序分析工具Pin在Windows系统中的安装和使用方法

    这篇日志其实很弱智,也是因为换了新电脑,实验环境不全(当然,做这个实验我是在虚拟机里,因为接下来想拿些恶意代码的数据),所以这里记录一下在Windows下怎么安装和使用Pin这个程序分析领域最常用的工 ...

  4. Windows系统中Xshell与Linux连接时遇到的问题

    前提条件:在Windows系统中已经安装了Xshell,并且安装了虚拟机软件和Linux系统 步骤1.在Linux系统中root用户下,使用ifconfig命令查看虚拟系统Linux的IP地址.如图1 ...

  5. 在Windows系统中安装集成的PHP开发环境

    原文:在Windows系统中安装集成的PHP开发环境 刚想学php的,又不会配置复杂php的环境,可以使用集成的,目前网上提供常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XA ...

  6. python - 在Windows系统中安装Pygame及导入Eclipse

    环境:python3.6(只有一个版本)+ windows10(64 bit)  + Eclipse+pydev python3.6安装完成后,会自带 easy_install 和 pip3,在Win ...

  7. linux中安装软件,查看、卸载已安装软件方法

    各种主流Linux发行版都采用了某种形式的包管理系统(PMS)来控制软件和库的安装. 软件包存储在服务器上,可以利用本地Linux系统上的PMS工具通过互联网访问.这些服务器称为仓库. 由于Linux ...

  8. Linux系统上查找已安装软件的路径

    在Linux系统上查找已安装软件路径的命令,以查找pcre的安装路径为例: [root@localhost doc]# rpm -ql pcre /lib64/libpcre.so. /lib64/l ...

  9. windows 如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中

    题目]如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中 一.概述 之前安装tensorflow的安装了anaconda并用它进行安装,anaconda ...

随机推荐

  1. C++ const用法 尽可能使用const [转载]

    C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助. 1.c ...

  2. 用消息机制解耦Activity跳转

    我见过的Activity方式有三种: 1, 默认的,在一个Activity里创建一个Intent,然后startActivity/startActivityForResult: 2, 给被跳转到的Ac ...

  3. hdu1536&&hdu3023 SG函数模板及其运用

    S-Nim Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status ...

  4. python操作memcached以及分布式

    memcached 是以 LiveJournal 旗下 Danga Interactive 公司的 Brad Fitzpatric 为首开发的一款软件.现在已成为 mixi.Facebook.Live ...

  5. c# Dictionary的遍历和排序

    c# Dictionary的遍历和排序 c#遍历的两种方式 for和foreach for: 需要指定首位数据.末尾数据.数据长度: for遍历语句中可以改变数据的值: 遍历规则可以自定义,灵活性较高 ...

  6. JAVA分布式事务原理及应用(转)

      JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据. JDBC驱动程序的JTA支持极大地增强了数据访问能力. 本文的目 ...

  7. Interleaving Positive and Negative Numbers

    Given an array with positive and negative integers. Re-range it to interleaving with positive and ne ...

  8. [转载]Python-第三方库requests详解

    Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...

  9. We will be discontinuing the Nitrous Development Platform and Cloud IDE on November 14th, 2016.

    我表示我很难过 Nitrous We will be discontinuing the Nitrous Development Platform and Cloud IDE on November ...

  10. 新建samba配置步骤

    Linux系统默认已经安装了Samba,但是没有安装Samba服务: 1,先查看安装情况:rpm -qa|grep samba 根据系统的安装情况选择下载或者通过光驱安装所缺的rpm包. 我的安装情况 ...