使用Python与Tkinter实现桌面软件自动更新与进度提醒

程一诺
程一诺
发布时间:2026-10-11| 3人浏览过
原创

针对桌面应用程序版本迭代需求,本文介绍如何使用Python结合Tkinter、requests与多线程技术,实现远程版本号比对、用户二次确认、后台安全下载及进度条实时显示。附带服务端JSON配置示例与完整客户端代码,帮助开发者快速构建轻量级软件更新模块。

功能目标与预期效果

该模块旨在为Python桌面程序提供一套完整的在线更新方案。启动时自动请求服务端接口获取最新版本号,若检测到新版本则弹出用户确认框;获得授权后,在后台开启独立线程下载更新包,同时通过Tkinter原生控件实时渲染下载进度。完成后自动关闭进度窗口并提示用户。以下为各阶段的标准UI表现:

主程序启动后的默认界面
检测到新版本时的进度条窗口
下载完成后的系统通知弹窗

准备条件

确保运行环境已安装基础依赖库。Tkinter随Python标准库自带,无需额外安装。网络请求需使用第三方库,提示交互推荐使用跨平台自动化库:

  • 核心依赖:tkinter、requests、_thread(或threading)、pyautogui
  • 环境要求:Python 3.6+,支持HTTP/HTTPS协议访问目标服务器
  • 前置操作:配置好服务端版本信息接口,返回标准JSON数据

真实操作顺序

第1步:设计服务端版本响应格式

明确接口返回结构,确保客户端能解析版本号与下载地址。服务端需保持以下JSON键名一致:

{
  "soft_version": "1.0.0",
  "soft_url": "http://example.com/update/client_v1.0.0.exe"
}

第2步:构建版本比对与确认逻辑

客户端启动时调用检查接口,提取本地版本与远程版本。采用移除小数点的整型比较法避免字符串排序歧义。若新版存在,调用弹窗组件征求用户同意:

# 省略部分内部方法,完整类定义见下方代码块
latest_version = json_result['soft_version']
if soft_dialog.check_version():
    if pyautogui.confirm(text='有新版本,是否更新', title='通知', buttons=['OK', 'Cancel']) == 'OK':
        soft_dialog.init_ui(root=app)
        soft_dialog.soft_download_with_thread()

第3步:执行后台下载与进度渲染

为防止阻塞主界面,将下载任务移交至子线程。通过HEAD请求预先获取文件总大小,随后以stream=True分块写入磁盘。每接收一块数据即更新DoubleVar变量,驱动进度条重绘。注意:更新可执行程序前务必对原安装目录或关键配置文件进行备份。

# 完整参考代码请见下方整体示例

第4步:清理线程状态与最终提示

文件写入完毕后停止进度动画,销毁临时窗口,最后由外部线程发送全局通知弹窗告知用户操作结束。此时可引导用户重启主程序加载新文件。

参考完整代码

import os
import _thread
import shutil
import subprocess
import sys
import requests
from tkinter import Tk, Label, IntVar, DoubleVar, HORIZONTAL, messagebox
from tkinter.ttk import Progressbar
import pyautogui

class SoftUpdateDialog:
    def __init__(self, soft_version):
        self.soft_update_url = 'http://your_server/web/share/version/update_demo'
        self.soft_version = soft_version

    def init_ui(self, root):
        self.root = root
        self.root.title('软件更新')
        self.root.geometry('300x100')
        self.progress_var = IntVar()
        self.label_var = DoubleVar()
        self.label_var.set(0.0)
        label = Label(self.root, text='正在更新软件,请等待···')
        label.pack(pady=5)
        self.progress_bar = Progressbar(self.root, length=200, mode='indeterminate')
        self.progress_bar.pack(pady=5)

    def tip_show(self, msg):
        """消息提示"""
        messagebox.showwarning('提示', msg)

    def soft_download_with_thread(self):
        '''开线程下载'''
        url = self.soft_update_url
        try:
            req = requests.get(url, stream=True, verify=False)
        except Exception:
            self.tip_show('请检查网络设置,无法检测到网络连接')
            return
        if req is None or str(req.status_code) != '200':
            self.tip_show('软件更新失败,请检查网络设置')
            return
        json_result = req.json()
        latest_version = json_result['soft_version']
        latest_soft_url = json_result['soft_url']
        if self.compare_version(latest_version):
            self.progress_var.set(0)
            self.progress_bar.start(60)
            _thread.start_new_thread(self._soft_download, (latest_soft_url, latest_version))

    def check_version(self):
        url = self.soft_update_url
        try:
            req = requests.get(url, stream=True, verify=False)
        except Exception:
            self.tip_show('请检查网络设置,无法检测到网络连接')
            return
        if req is None or str(req.status_code) != '200':
            self.tip_show('软件更新失败,请检查网络设置')
            return
        json_result = req.json()
        latest_version = json_result['soft_version']
        return self.compare_version(latest_version)

    def _update_progressbar(self):
        '''更新进度条'''
        self.progress_bar['value'] = self.label_var.get()

    def _end_update(self):
        '''结束更新'''
        self.progress_bar.stop()
        self.root.destroy()

    def get_remote_file_size(self, url, proxy=None):
        """通过content-length头获取远程文件大小"""
        try:
            req = requests.head(url, proxies={'http': proxy, 'https': proxy} if proxy else None, verify=False)
            fileSize = int(req.headers.get('Content-Length', 0))
            return fileSize
        except Exception:
            return 0

    def _soft_download(self, latest_url, latest_version):
        '''软件下载'''
        self.label_var.set(0.0)
        lastest_name = os.path.basename(latest_url)
        lastest_size = self.get_remote_file_size(latest_url)
        start_size = 0
        with requests.get(latest_url, stream=True, verify=False) as r:
            with open(lastest_name, "wb") as f:
                for chunk in r.iter_content(chunk_size=1024):
                    if not chunk:
                        continue
                    start_size += len(chunk)
                    f.write(chunk)
                    f.flush()
                    self.label_var.set(100.0 * start_size / lastest_size)
        print('>> ok')
        self._end_update()

    def compare_version(self, latest_version):
        return int(self.soft_version.replace('.', '')) < int(latest_version.replace('.', ''))

if __name__ == '__main__':
    app = Tk()
    app.geometry('0x0')
    soft_dialog = SoftUpdateDialog(soft_version='0.0.5')
    if soft_dialog.check_version() and pyautogui.confirm(text='有新版本,是否更新', title='通知', buttons=['OK', 'Cancel'])=='OK':
        soft_dialog.init_ui(root=app)
        soft_dialog.soft_download_with_thread()
        app.mainloop()
        pyautogui.alert(text='下载完成!', title='通知', button='好的👌🏻')

排错与维护提示

代码中使用了verify=False跳过SSL证书校验,适用于内网或测试环境。生产环境建议替换为有效的CA证书或移除该参数以确保传输安全。若进度条卡顿或未显示,请检查子线程是否正确触发了_update_progressbar逻辑,且主线程未因长时间同步调用而冻结。下载路径默认为脚本同级目录,可根据业务需求修改open()中的保存位置。所有涉及文件覆盖的操作,强烈建议在运行更新脚本前建立完整的项目备份清单。

简要总结

通过组合Tkinter界面控件、requests流式下载与Python多线程机制,可低成本搭建可靠的桌面端OTA升级通道。合理控制校验频率与分块大小,既能保证低带宽下的稳定拉取,又能提供平滑的用户体验反馈。以上就是使用Python与Tkinter实现桌面软件自动更新与进度提醒的详细内容,更多关于Python桌面应用开发、Tkinter图形界面设计的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。