Python编写的桌面图形程序,如何实现版本更新和下载?

Irene181
• 阅读 1862

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

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

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

程序更新

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

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

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

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

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

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

检测更新

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

Python编写的桌面图形程序,如何实现版本更新和下载?

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

下载更新

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

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

下载有两种方式:

  1. 直接通过主程序进行下载;

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

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

Python编写的桌面图形程序,如何实现版本更新和下载?

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

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

Python编写的桌面图形程序,如何实现版本更新和下载?

程序文件的下载,我们可以直接使用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编写的桌面图形界面程序的更新检测、下载和覆盖安装。

**-----**------**-----**---**** End **-----**--------**-----**-****

往期精彩文章推荐:

Python编写的桌面图形程序,如何实现版本更新和下载?

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/0041QasXDSPyhrT1i51w5w,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Karen110 Karen110
3年前
一文带你读懂PyQt:用Python做出与C++一样的GUI界面应用程序
\一、简介Python标准库更多的适合处理后台任务,唯一的图形库tkinter使用起来很不方便,所以后来出现了针对Python图形界面开发的扩展库,今天老猿要介绍的是主流Python图形界面扩展库之一的PyQt。在介绍PyQt之前,必须先简单介绍一下Qt。Qt是一个C可视化开发平台,是一个跨平台的C图形用户界面应用程序框架(CGUI)
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
3年前
4cast
4castpackageloadcsv.KumarAwanish发布:2020122117:43:04.501348作者:KumarAwanish作者邮箱:awanish00@gmail.com首页:
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这