在Python中我们有很多种方案来编写桌面图形用户界面程序,譬如内置的 Tkinter 、强大的 PyQt5 和 PySide2 ,还有 wxPython 。借助这些或内置或第三方的模块,我们可以轻松地编写跨平台的桌面图形界面程序。

同时,我们还能直接使用 PyInstaller 、 Nuitka 、 cx_Freeze 等 Python 第三方程序打包模块,将编写好桌面图形界面程序打包为各个平台的二进制可执行程序文件,比如 Windows 下的 exe 程序执行文件。

通常我们会将程序按需打包为单个的 exe可执行文件 或包含整个文件夹的可执行文件。

文章目录

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

程序更新

随着版本的迭代和功能的优化,我们编写的程序会需要进行更新。

在 Web 应用中,这个问题几乎不需要处理,因为只要服务器更新了,浏览器打开的页面或功能都将是最新的。

而在桌面图形界面程序中,则有点棘手。因为我们打包好的程序都是离线分发的,按照以往的流程,我们需要重新打包程序,然后,在某个页面放上新版本程序的下载链接,最后提醒使用者下载更新。

如果使用者没有注意到,那么就凉拌了。

如何解决呢?我们需要在编写的桌面图形界面程序中,额外添加一个更新机制,用于检测更新、下载更新和完成更新。

下面我们来介绍一下这个流程。

检测更新

要实现程序的更新,我们首先需要让程序能够检测到软件存在更新。在这里,我们需要一个远程的更新服务器,来提供更新的检测响应。

然后,在程序启动的时候,调用一个子线程,向远程服务器发起请求,以获得是否需要进行更新。

下载更新

如果没有程序的更新,自然就略过了。

如果有程序的更新,我们就需要对新版本的程序进行下载。

下载有两种方式:

  1. 直接通过主程序进行下载;
  2. 编写一个单独的更新程序,主程序调用更新程序进行下载;

直接通过主程序进行下载的方式对于下载是可行的,但是没法自己覆盖更新自己。所以我们选择第二种方式。

主程序通过一个子线程使用 subprocess.Popen() 调用打包为单个文件的更新程序。

然后更新程序再核对一遍是否存在版本更新,如果存在更新,那么继续请求远程服务器,下载新版本的程序。

程序文件的下载,我们可以直接使用 requests 模块,示例代码如下所示:

def work(self):
# 新建一个文件对象
temp_file = os.path.join(self.download_path,'update.zip') # 指定更新包下载的路径
logger.info("下载临时文件路径为:{}".format(temp_file))
with open(temp_file,'wb') as self.fileobj:
# 请求更新文件包
f = requests.get(self.download_url, stream=True)
# 写入文件
offset = 0
for chunk in f.iter_content(chunk_size=self.buffer):
if not chunk:
break
self.fileobj.seek(offset)
self.fileobj.write(chunk)
offset = offset + len(chunk)
proess = offset / int(self.filesize) * 100
# logger.info("写入块:{},{}".format(offset,proess))
self.download_proess_signal.emit(int(proess))

解压覆盖

新版本的程序下载完,我们就需要将其解压到原有的文件夹了。这时候,更新程序和主程序分开打包的好处就出来了,我们通过更新程序将正在运行的主程序进程结束掉,然后将新版本的程序压缩包解压覆盖现有程序所在的文件夹:

def work(self):
# 1.杀死主程序进程
for proc in psutil.process_iter():
if proc.name() == 'xxx.exe':
proc.kill()
# 2.获取程序本地路径
current_path = os.path.dirname(os.path.abspath(__file__))
logger.info("当前程序路径:{}".format(current_path))
# 3.解压新版本压缩包到程序本地路径
update_file_path = os.path.join(self.download_temp_path, 'update.zip')
shutil.unpack_archive(
filename=update_file_path,
extract_dir=current_path
)
# 4.删除临时文件夹和文件
os.remove(update_file_path)
shutil.rmtree(self.download_temp_path)

这样,我们就实现了Python编写的桌面图形界面程序的更新检测、下载和覆盖安装。

Python编写的桌面图形界面程序实现更新检测和下载安装的更多相关文章

  1. python使用easygui写图形界面程序

    我 们首先下载一个类库easygui,它是一个Python用于简单开发图形化界面的类库,打开easygui的下载网页 http://sourceforge.net/projects/easygui/? ...

  2. 在桌面Linux环境下开发图形界面程序的方案对比

    在Linux下开发GUI程序的方法有很多,比如Gnome桌面使用GTK+作为默认的图形界面库,KDE桌面使用Qt作为默认的图形界面库,wxWidgets则是另一个使用广泛的图形库,此外使用Java中的 ...

  3. linux启动后自动登录并运行自定义图形界面程序

    在<Ubuntu CTRL+ALT+F1~F6 进入命令模式后不支持中文显示的解决办法>一文中提到linux启动在以后运行一个独占显示器的图形程序的两种办法. 1.不启动xserver,使 ...

  4. 在ubuntu上使用wxWidgets成功开发一个图形界面程序

    编译wxWidgets 下载最新版的源码,wxWidgets-3.0.2.wxWidgets在liunx是通过wxGTK实现的.wxGTK和wxWidgets的源码打包在一起.wxGTK依赖GTK+, ...

  5. Quartz(GUI)图形界面程序----Quartz Web

    下载.设置和运行Quartz(GUI)图形界面程序----Quartz Web 一.获取Quartz Web程序(Quartz GUI).早期的 Quartz 框架开发者意识到一个 GUI 对于某类用 ...

  6. 用Python编写简单的发红包程序和计算器原理

    用Python编写简单的发红包程序: 第一种解法:数轴方法解决 import random def red_packet(money,num): money = money * 100 #将钱数转换成 ...

  7. Win32简单图形界面程序逆向

    Win32简单图形界面程序逆向 前言 为了了解与学习底层知识,从 汇编开始 -> C语言 -> C++ -> PE文件 ,直至今天的Win32 API,着实学的令我头皮发麻(笑哭). ...

  8. 第十五章 使用PyQt进行Python图形界面程序开发

    在基础知识部分的最后一章<第十三章 Python基础篇结束章>的<第13.3节 图形界面开发tkinter>简单介绍了Python内置图形界面标准库tkinter,当时特别强调 ...

  9. 使用PyQt进行Python图形界面程序开发文章目录

    ☞ ░ 前往老猿Python博文目录 ░ PyQt入门知识原来是作为老猿Python<Python基础教程目录>后的进阶学习章节存在,最近不少专栏作者提醒老猿整体的博文内容不错,但博文没有 ...

随机推荐

  1. Redis安装与运行讲解

    第一步:安装Redis 打开网址:https://github.com/MicrosoftArchive/redis/releases 因为版本比较多,最新版已经是3.2.100,我们选择3.0.50 ...

  2. VSCode下,项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

    vscode下webpack错误:无法将“webpack”项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次. 解决方法: 1.因为 ...

  3. java 面向对象(二十四):interface:接口

    interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...

  4. day2:Number,tuple,str,list,set,dict

    # ### Number ( int float bool complex) 1.int 整型 (正整数 0 负整数)intvar = 1print(intvar) # type 获取值的类型res ...

  5. 关于Mint-UI中loadmore组件的兼容性问题

    源代码 遇到的问题 写完了之后数据加载,渲染等等都是没有问题的,但是测试总是提上滑刷新不能用,因为是远程开发,测试提就得改,看代码看文档,看半天看不出来问题,想到了兼容性问题,发现也有人遇到这个坑.安 ...

  6. Python 3基础教程8-if else语句

    终于更新到了,教程8, 如果对python软件测试.接口测试.自动化测试.面试经验交流.感兴趣可以加君羊软件测试交流: 1079636098,还会有同行一起技术交流. 本文介绍if else语句,不多 ...

  7. P1866 编号

    大致题意: 求太郎的n只兔子的编号的排列种数 基本思路: 每只兔子都有一个范围,那么每只兔子的范围就是这只兔子选择编号的种数. 以5 8为例,第一只兔子有5种,第二只兔子有8种,而第一只兔子选择后,第 ...

  8. 资深CIO介绍如何选型OA系统的?

    OA办公系统成为企业管理的标配软件,在于可有效加强组织管理能力,提高员工协同效率,助力企业科学决策,合理分配企业资源,提升企业综合实力与市场竞争力.企业OA选型的经验总结来说也就是品牌.技术.产品.服 ...

  9. scrapyd+gerapy的项目部署

    scrapyd+gerapy的项目部署: 简单学习,后续跟进完善 声明: 1)仅作为个人学习,如有冒犯,告知速删! 2)不想误导,如有错误,不吝指教! 环境配置: scrapyd下载: pip ins ...

  10. javascript兼容性:展开运算符 ... 的降级

    展开运算符 ... 是一个很好用的ES6新特性,用的好的话,可以节约很多代码. 但是作为ES6特性,它有兼容性问题,而且Babal(在线转码网页)并不会转换展开运算符. 展开运算符大体分为两种用法:展 ...