记得有一次打开一个单独exe程序,点击btn中的一个帮助说明按钮,在同级目录下就多出一个help.chm 文件并自动打开。

那这个exe肯定是把help.chm 打包到exe中,当我触发“帮助”按钮的时候另存为help.chm 并打开该文件。

所以我在想,Pyqt打包资源是否也可以另存为后打开资源中的文件呢?然后就有了下文

一、 生成资源文件

我们先找几个资源文件

比如:

用Qt Designer中的资源浏览器把资源素材添加并保存为resexe.qrc 文件

resexe.qrc文件:

  1. <RCC>
  2. <qresource prefix="exe">
  3. <file>aaa/ResHacker3.5.exe</file>
  4. </qresource>
  5. <qresource prefix="chm">
  6. <file>aaa/PyQt4_Tutorial.chm</file>
  7. </qresource>
  8. <qresource prefix="txt">
  9. <file>aaa/texta.txt</file>
  10. </qresource>
  11. <qresource prefix="mp3">
  12. <file>aaa/apples.mp3</file>
  13. </qresource>
  14. </RCC>

将qrc资源文件转换为py

  1. pyrcc4 -o resexe.py resexe.qrc

二、编写逻辑代码

用Python读取保存二进制文件是这样的:

  1. #读取资源文件
  2. originalfile = open('F:/QQ.exe','rb')
  3. filedata = originalfile.read()
  4. originalfile.close()
  5. #指定为字节类型
  6. savedata = bytearray(filedata)
  7. savefile = open('C:/QQ_res.exe','wb')
  8. savefile.write(savedata)
  9. savefile.close()

但在Pyqt中py原生的open() 方法是找不到文件的:
因为Qt qrc转换的资源必须要用":"开始引用,例如:

  1. self.setWindowIcon(QIcon(':qq.ico'))

以下代码是错误的:

  1. originalfile = open(':mp3/aaa/apples.mp3','rb')
  2. filedata = originalfile.read()
  3. originalfile.close()
  4. savedata = bytearray(filedata)
  5. savefile = open('C:/apples.mp3','wb')
  6. savefile.write(savedata)
  7. savefile.close()

报错:

  1. Traceback (most recent call last):
  2. originalfile = open(':mp3/aaa/apples.mp3','rb')
  3. IOError: [Errno 22] invalid mode ('rb') or filename: ':mp3/aaa/apples.mp3'

所以直接使用Py的open()方法是无法获取Qt qrc资源文件的。

要获取qrc里面的资源文件必须要使用Qt内置的QFile

下面有两个方法

  • QFile的copy()方法
  1. QtCore.QFile.copy(':mp3/aaa/apples.mp3','C:/appless.mp3')

可直接将资源文件copy到指定的目录

QFile.copy文档:

bool QFile.copy (self, QString newName)

Copies the file currently specified by fileName() to a file called newName. Returns true if successful; otherwise returns false.

Note that if a file with the name newName already exists, copy() returns false (i.e. QFile will not overwrite it).

The source file is closed before it is copied.

See also setFileName().

bool QFile.copy (QString fileName, QString newName)

This is an overloaded function.

Copies the file fileName to newName. Returns true if successful; otherwise returns false.

If a file with the name newName already exists, copy() returns false (i.e., QFile will not overwrite it).

See also rename().

  • QFile的QIODevice.readAll()
  1. originfiles = QtCore.QFile(':mp3/aaa/apples.mp3')
  2. originfiles.open(QtCore.QFile.ReadOnly)
  3. origindata = originfiles.readAll()
  4. savefiledata = bytearray(origindata)
  5. savefile = open('C:/appless.mp3', 'wb')
  6. savefile.write(savefiledata)
  7. savefile.close()

QFile以只读模式打开资源':mp3/aaa/appless.mp3', readAll() 返回二进制QByteArray, 再通过Py的open() 以'wb'模式写入二进制数据

QIODevice.readAll文档:

object QIODevice.read (self, long maxlen)

Reads at most maxSize bytes from the device into data, and returns the number of bytes read. If an error occurs, such as when attempting to read from a device opened in WriteOnly mode, this function returns -1.

0 is returned when no more data is available for reading. However, reading past the end of the stream is considered an error, so this function returns -1 in those cases (that is, reading on a closed socket or after a process has died).

See also readData(), readLine(), and write().

QByteArray QIODevice.readAll (self)

This is an overloaded function.

Reads all available data from the device, and returns it as a QByteArray.

This function has no way of reporting errors; returning an empty QByteArray() can mean either that no data was currently available for reading, or that an error occurred.

完整代码如下:

  1. # -*- coding: utf-8 -*-
  2. '''
  3. 下载打包资源文件中的资源
  4. '''
  5.  
  6. from PyQt4 import QtCore, QtGui
  7.  
  8. import sys, os
  9.  
  10. reload(sys)
  11. sys.setdefaultencoding("utf-8")
  12.  
  13. class Mwindow(QtGui.QDialog):
  14. def __init__(self):
  15. super(Mwindow, self).__init__()
  16. self.resize(100, 150)
  17. self.setWindowTitle(u'下载打包文件中的资源文件')
  18. self.down1 = QtGui.QPushButton(u'下载ResHacker')
  19. self.down2 = QtGui.QPushButton(u'下载PyQt4_Tutorial')
  20. self.down3 = QtGui.QPushButton(u'下载texta文本')
  21. self.down4 = QtGui.QPushButton(u'下载apples.mp3')
  22. self.checked = QtGui.QCheckBox(u'同时打开文件')
  23. self.checked.setCheckState(QtCore.Qt.Checked)
  24. mylayout = QtGui.QGridLayout()
  25. mylayout.addWidget(self.down1, 0, 0)
  26. mylayout.addWidget(self.down2, 0, 2)
  27. mylayout.addWidget(self.down3, 0, 1)
  28. mylayout.addWidget(self.down4, 1, 0)
  29. mylayout.addWidget(self.checked, 1, 2)
  30. self.setLayout(mylayout)
  31. self.connect(self.down1, QtCore.SIGNAL('clicked()'), self.download)
  32. self.connect(self.down2, QtCore.SIGNAL('clicked()'), self.download)
  33. self.connect(self.down3, QtCore.SIGNAL('clicked()'), self.download)
  34. self.connect(self.down4, QtCore.SIGNAL('clicked()'), self.download)
  35.  
  36. def download(self):
  37.  
  38. import resexe
  39.  
  40. senderc = str(self.sender().text())
  41. downObject = ''
  42. extend = 'All Files (*.*)'
  43. if senderc.find('appl') > 0:
  44. downObject = ':mp3/aaa/apples.mp3'
  45. extend = 'mp3 Files (*.mp3)'
  46. if senderc.find('ResHacker') > 0:
  47. downObject = ':exe/aaa/ResHacker3.5.exe'
  48. extend = 'exe Files (*.exe)'
  49. if senderc.find('PyQt4_Tutorial') > 0:
  50. downObject = ':chm/aaa/PyQt4_Tutorial.chm'
  51. extend = 'chm Files (*.chm)'
  52. if senderc.find('text') > 0:
  53. downObject = ':txt/aaa/texta.txt'
  54. extend = ' Files (*.txt)'
  55.  
  56. fileName = QtGui.QFileDialog.getSaveFileName(self, u"文件保存", "C:/", extend)
  57. if fileName:
  58. # 方法一
  59. # QtCore.QFile.copy(downObject,fileName)
  60. #方法二
  61. originfiles = QtCore.QFile(downObject)
  62. originfiles.open(QtCore.QFile.ReadOnly)
  63. origindata = originfiles.readAll()
  64. savefiledata = bytearray(origindata)
  65. savefile = open(fileName, 'wb')
  66. savefile.write(savefiledata)
  67. savefile.close()
  68.  
  69. openfile = self.checked.isChecked() #判断选择打开文件
  70. if openfile:
  71. os.system(str(fileName))
  72. else:
  73. QtGui.QMessageBox.question(self, (u'提示'), (u'保存成功'), QtGui.QMessageBox.Yes)
  74.  
  75. if __name__ == '__main__':
  76. app = QtGui.QApplication(sys.argv)
  77. mainWin = Mwindow()
  78. mainWin.show()
  79. sys.exit(app.exec_())

三、将代码打包成二进制exe

我们使用Pyinstaller打包

  1. if __name__ == '__main__':
  2. from PyInstaller.main import run
  3. params=['downloadres.py', '-F', '-w', '--icon=favicon.ico']
  4. run(params)

生成downloadres.exe

四、运行效果


如果可以,接下来我们也可以做一个tcp获取网络资源并下载的Pyqt程序。

Pyqt 获取打包二进制文件中的资源的更多相关文章

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

    开始之前的基础知识 1. 获取软件列表 在Python的标准库中,_winreg可以操作Windows的注册表.获取已经安装的软件列表一般是读去windows的注册表: SOFTWARE\Micros ...

  2. SpringBoot 项目打包后获取不到resource下资源的解决

    SpringBoot 项目打包后获取不到resource下资源的解决 在项目中有几个文件需要下载,然后不想暴露真实路径,又没有CDN,便决定使用接口的方式来获取文件.最初的时候使用了传统的方法来获取文 ...

  3. Java如何获取当前的jar包路径以及如何读取jar包中的资源

    写作业的时候要输出一个record.dat文件到jar包的同级目录,但是不知道怎么定位jar包的路径.百度到的方法不很靠谱,所以在这里记录一下. 一:使用类路径 String path = this. ...

  4. 2.QT中使用资源文件,程序打包

     1 程序中使用资源文件 A  一个QT空项目 B  右击项目,添加新文件 添加后的效果是 C  右击main.prc,选择"添加现有项",找到要使用的资源文件.最终的效果是: ...

  5. Java中获取classpath路径下的资源文件

    ClassLoader 提供了两个方法用于从装载的类路径中取得资源: public URL  getResource (String name); public InputStream  getRes ...

  6. PyQt(Python+Qt)学习随笔:Qt Designer中图像资源的使用及资源文件的管理

    一.概述 在Qt Designer中要使用图片资源有三种方法:通过图像文件指定.通过资源文件指定.通过theme主题方式指定,对应的设置界面在需要指定图像的属性栏如windowIcon中通过点击属性设 ...

  7. 【Azure 环境】【Azure Developer】使用Python代码获取Azure 中的资源的Metrics定义及数据

    问题描述 使用Python SDK来获取Azure上的各种资源的Metrics的名称以及Metrics Data的示例 问题解答 通过 azure-monitor-query ,可以创建一个 metr ...

  8. springmvc获取jar中的静态资源与jar包中的资源互相引用问题

    1.首先看jar中的文件位置 2.在web工程中引用该jar 并且在springmvc文件中配置路径 如果有多个路径可用逗号隔开 3.在web工程找jsp页面如何引用 这样就可以了 关于jar中的资源 ...

  9. 打包jar文件 外部调用资源 so等

    一个非常好的从jar文件中加载so动态库方法,在android的gif支持开源中用到.这个项目的gif解码是用jni c实现的,避免了OOM等问题. 项目地址:https://github.com/k ...

随机推荐

  1. redis 的源码编译安装

    首先我们下载软件包到指定的目录下 tar -zxvf redis-2.8.19.tar.gz cd redis-2.8.19 make make PREFIX=/usr/local/redis ins ...

  2. Redis 学习(二)

    Redis可以存储以下5种数据类型 1. String 字符串 整数 浮点 2. List   一个链表 3. Set  无序收集器 4. Hash  无序散列表 5. Zset   有序集合

  3. 一些js 插件的作用

    前言: 从一些开源网站上下载下来的 后台管理系统模板一般会有很多的js ,其js 的功能是什么呢?这里随手查询了一下,记录下来 正文: 1.zDialog.js 各种弹窗插件详细案例:http://w ...

  4. .dwg(sw)-exb

    尺寸风格:除了标准外合并,合并好后删除. 文本风格:除了标准外合并,合并好后删除.

  5. 教你一招:EXCEL单元格随机生成字母

    =CHAR(RANDBETWEEN(1,4)+65) 65代表大写字母A,依次类推 1代表从A开始 4代表到D结束

  6. php 实用例子:购物车 涉及session与ajax

    login: <div>用户名:<input type="text" id="uid" /></div><div> ...

  7. mysql5.7导入csv文件

    环境: Windows10企业版X64 mysql5.7免安装版(从5.6版本开始,官方不再提供64位的msi版本) 运行mysqld.exe启动mysql进程. 用root登录mysql: mysq ...

  8. Elasticsearch集群状态脚本及grafana监控面板导出的json文件

    脚本文件: #!/usr/bin/env python import datetime import time import urllib import json import urllib2 imp ...

  9. Python Day6

    面向对象 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强...&qu ...

  10. Thinkphp中controller控制器根据curl函数请求数据

    public function member(){ $url="http://aitequn.tjnit.com/UserAction_findAllUser"; $ch =cur ...