最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+PyQt5開發(fā)一個Windows EXE程序在線更新工具

 更新時間:2026年01月04日 09:33:03   作者:weixin_46244623  
這篇文章主要為大家詳細介紹了Python+PyQt5開發(fā)一個Windows EXE程序在線更新工具,可以自動檢測新版本并完成在線升級,感興趣的小伙伴可以了解下

一、前言

在使用 PyQt5 + PyInstaller 開發(fā) Windows 桌面工具時,一個非?,F(xiàn)實的問題是:

程序如何自動檢測新版本,并完成在線升級?

本文基于一個真實可用、已落地的更新方案,實現(xiàn)了:

  • 遠程版本號檢測
  • 語義化版本對比
  • 更新提示彈窗
  • 子線程下載更新包
  • 實時下載進度條
  • ZIP 解壓
  • EXE 自動替換
  • 舊版本自動備份
  • 更新完成后安全退出

非常適合 工具類 / 內(nèi)部系統(tǒng) / 單機 EXE 程序。

二、運行效果說明

整體更新流程如下:

  • 點擊「獲取最新版本」
  • 請求遠程 version.txt
  • 發(fā)現(xiàn)新版本 → 彈窗提示
  • 用戶確認 → 下載 update.zip
  • 顯示下載進度條
  • 解壓更新文件
  • 備份舊 EXE
  • 替換新 EXE
  • 提示升級完成并退出程序

三、環(huán)境與依賴說明

Python 版本

Python 3.8+

pip 依賴安裝

pip install PyQt5
pip install requests
pip install packaging

(如需打包 EXE)

pip install pyinstaller

四、服務(wù)器端準備

版本號文件(version.txt)

1.2.0

更新包(update.zip)

update.zip
├── update.exe
├── logo.png(可選)

五、完整代碼

SoftVesion.py
def current_version():
    """
    Returns the version of the package
    """
    return "1.1.0"
def latest_version():
    """
    Returns the latest version of the package
    """
    return "1.1.0"
def upgrade_date():
    """
    Returns the time of the upgrade
    """
    return "2024年1月19日"
def current_title():
    """
    Returns the title of the package
    """
    return "Excel常用小工具"
def remote_version_url():
    """
    Returns the url of the latest version
    """
    return "http://82.157.62.197:97/version.txt"
def update_url():
    """
    Returns the url of the version info
    """
    return "http://192.168.31.219:8080/update.zip"

UpdateApp.py

import os
import zipfile
import requests
from packaging import version
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtWidgets import QApplication,QDialog, QVBoxLayout,QMainWindow, QPushButton, QMessageBox, QProgressDialog,QLabel,QAction,QDesktopWidget
import shutil
from .SoftVesion import current_version,latest_version,remote_version_url,update_url,current_title
from PyQt5.QtGui import QStandardItemModel, QStandardItem,QIcon
import sys
import time
import subprocess
class DownloadThread(QThread):
    progressChanged = pyqtSignal(int)
    downloadFinished = pyqtSignal()
    unableToFetchUpdateLink = pyqtSignal()

    def __init__(self, url, save_path):
        super().__init__()
        self.url = url
        self.save_path = save_path

    def run(self):
        try:
            response = requests.get(self.url, stream=True)
            if response.status_code == 200:
                total_size = int(response.headers.get('content-length', 0))

                downloaded_size = 0
                with open(self.save_path, 'wb') as file:
                    for data in response.iter_content(chunk_size=8192):
                        file.write(data)
                        downloaded_size += len(data)
                        progress = int((downloaded_size / total_size) * 100)
                        self.progressChanged.emit(progress)

                self.downloadFinished.emit()
            else:
                print("Error fetching update link:")
                self.unableToFetchUpdateLink.emit()
        except Exception as e:
            print("Error fetching update link:", e)
            self.unableToFetchUpdateLink.emit()

class UpdateApp(QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.current_version = current_version()  # 當(dāng)前應(yīng)用程序版本號
        self.latest_version = latest_version()
        self.progress_dialog = None
        self.download_thread = None
        self.remote_version_url= remote_version_url()
        self.update_url = update_url()
        self.init_ui()
        #self.show_update_notification()
    def move_to_center(self, widget):
        # 將 widget 移動到屏幕中央
        desktop_center = QDesktopWidget().availableGeometry().center()
        widget_frame = widget.frameGeometry()
        widget_frame.moveCenter(desktop_center)
        widget.move(widget_frame.topLeft())
    def init_ui(self):
        self.setFixedSize(300, 200)
        self.setWindowTitle("檢查更新")
        icon = QIcon("icon.png")
        self.setWindowIcon(icon)

        self.version_label = QLabel("當(dāng)前版本號: " + self.current_version, self)
        self.version_label.setAlignment(Qt.AlignCenter) 
        self.version_label.setGeometry(100, 10, 110, 20)

        self.update_button = QPushButton("獲取最新版本", self)
        self.update_button.setGeometry(100, 60, 110, 40)
        self.update_button.clicked.connect(self.show_update_notification)

        if self.download_thread:
            self.download_thread.unableToFetchUpdateLink.connect(self.show_unable_to_fetch_update_link)

    def show_unable_to_fetch_update_link(self):
        QMessageBox.critical(self, "無法獲取更新鏈接", "無法獲取更新鏈接,請檢查網(wǎng)絡(luò)連接。")

    def update_app(self):
        try:
            remote_version = self.get_remote_version()
            if version.parse(remote_version) > version.parse(self.current_version):
                if self.has_network_connection():
                    self.perform_upgrade()
                else:
                    QMessageBox.information(self, "無法獲取版本號", "無法獲取遠程版本號,請檢查網(wǎng)絡(luò)連接。")
            else:
                QMessageBox.information(self, "無需升級", "當(dāng)前應(yīng)用程序已經(jīng)是最新版本。")
        except:
            QMessageBox.information(self, "無法獲取版本號", "無法獲取遠程版本號,請檢查網(wǎng)絡(luò)連接。")

    def get_remote_version(self):
        try:
            response = requests.get(self.remote_version_url)
            if response.status_code == 200:
                return response.text.strip()
            return self.latest_version
        except:
            return self.latest_version

    def perform_upgrade(self):
        update_url = self.update_url
        temp_zip_path = "temp_update.zip"

        self.download_thread = DownloadThread(update_url, temp_zip_path)
        self.download_thread.progressChanged.connect(self.update_progress_bar)
        self.download_thread.downloadFinished.connect(self.handle_download_finished)

        self.progress_dialog = QProgressDialog("正在下載更新...", None, 0, 100, self)
        self.progress_dialog.setWindowModality(Qt.WindowModal)
        self.progress_dialog.setAutoClose(False)
        self.progress_dialog.setAutoReset(False)
        self.progress_dialog.setWindowTitle("下載進度")
        self.move_to_center(self.progress_dialog)
        self.progress_dialog.canceled.connect(self.download_thread.quit)

        self.download_thread.start()

    def update_progress_bar(self, progress):
        self.progress_dialog.setValue(progress)

    def handle_download_finished(self):
        self.progress_dialog.hide()
        if os.path.exists("temp_update.zip"):
            self.process_download("temp_update.zip")
            os.remove("temp_update.zip")
        sys.exit()

    def has_network_connection(self):
        try:
            requests.get(remote_version_url(), timeout=5)
            return True
        except:
            return False

    def show_update_notification(self):
        try:
            remote_version = self.get_remote_version()
            if version.parse(remote_version) > version.parse(self.current_version):
                reply = QMessageBox.question(
                    self, "版本更新提示",
                    f"有新版本可用:{remote_version}\n您當(dāng)前的版本:{self.current_version}\n是否要更新?",
                    QMessageBox.Yes | QMessageBox.No
                )
                if reply == QMessageBox.Yes:
                    self.update_app()
            else:
                QMessageBox.information(self, "版本更新提示", "您當(dāng)前的版本是最新版本。")
        except:
            pass

if __name__ == "__main__":
    app = QApplication([])
    window = UpdateApp()
    window.show()
    app.exec_()

六、關(guān)鍵設(shè)計說明

使用 QThread 防止界面卡死

使用 packaging.version 進行版本比較

ZIP 更新包支持擴展文件

EXE 覆蓋前自動備份

更新完成后安全退出

七、適用場景

PyQt5 工具軟件

內(nèi)部辦公系統(tǒng)

單機 EXE 程序

不依賴第三方更新框架

八、總結(jié)

本文提供的是一個 可直接落地、真實可用 的 PyQt5 自動更新方案,無需復(fù)雜服務(wù)器邏輯,維護成本極低。

到此這篇關(guān)于Python+PyQt5開發(fā)一個Windows EXE程序在線更新工具的文章就介紹到這了,更多相關(guān)Python EXE程序更新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python OpenCV 彩色與灰度圖像的轉(zhuǎn)換實現(xiàn)

    Python OpenCV 彩色與灰度圖像的轉(zhuǎn)換實現(xiàn)

    為了加快處理速度在圖像處理算法中,往往需要把彩色圖像轉(zhuǎn)換為灰度圖像,本文主要介紹了Python OpenCV 彩色與灰度圖像的轉(zhuǎn)換實現(xiàn),感興趣的可以了解一下
    2021-06-06
  • Django logging配置及使用詳解

    Django logging配置及使用詳解

    這篇文章主要介紹了Django logging配置及使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • 使用TensorFlow創(chuàng)建生成式對抗網(wǎng)絡(luò)GAN案例

    使用TensorFlow創(chuàng)建生成式對抗網(wǎng)絡(luò)GAN案例

    這篇文章主要為大家介紹了使用TensorFlow創(chuàng)建生成式對抗網(wǎng)絡(luò)GAN案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 如何在Python中進行異常處理

    如何在Python中進行異常處理

    這篇文章主要介紹了如何在Python中進行異常處理,Python中使用用異常對象(exception object)表示異常情況,當(dāng)程序運行遇到錯誤后,就會觸發(fā)發(fā)異常,下文關(guān)于異常處理的相關(guān)內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03
  • python如何將圖片轉(zhuǎn)換素描畫

    python如何將圖片轉(zhuǎn)換素描畫

    這篇文章主要介紹了python如何將圖片轉(zhuǎn)換素描畫,幫助大家更好的用python處理圖片,感興趣的朋友可以了解下
    2020-09-09
  • Python熱重載調(diào)試新利器問題解決

    Python熱重載調(diào)試新利器問題解決

    Reloading是一個Python工具庫,它讓我們可以在每次迭代之前從源代碼中重新加載(或函數(shù))而不丟失任何當(dāng)前已執(zhí)行過程,這篇文章主要介紹了Python熱重載調(diào)試新利器,需要的朋友可以參考下
    2024-06-06
  • Python全棧之單項循環(huán)

    Python全棧之單項循環(huán)

    這篇文章主要為大家介紹了Python單項循環(huán),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • pytorch 梯度NAN異常值的解決方案

    pytorch 梯度NAN異常值的解決方案

    這篇文章主要介紹了pytorch 梯度NAN異常值的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Python查找算法之分塊查找算法的實現(xiàn)

    Python查找算法之分塊查找算法的實現(xiàn)

    這篇文章主要介紹了Python查找算法之分塊查找算法的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 解決Pycharm雙擊圖標啟動不了的問題(JetBrains全家桶通用)

    解決Pycharm雙擊圖標啟動不了的問題(JetBrains全家桶通用)

    這篇文章主要介紹了Pycharm雙擊圖標啟動不了(JetBrains全家桶通用),本文給大家分享問題及解決方法,需要的朋友可以參考下
    2020-08-08

最新評論

漠河县| 台中县| 八宿县| 龙川县| 环江| 开鲁县| 拉萨市| 武城县| 柳河县| 工布江达县| 金昌市| 太仓市| 南宁市| 雷波县| 大同县| 张家港市| 台前县| 凤山县| 高州市| 静宁县| 磴口县| 伊金霍洛旗| 伊通| 方山县| 定结县| 庄浪县| 津市市| 昌乐县| 阿巴嘎旗| 肃北| 哈密市| 泸州市| 信宜市| 遵化市| 宁晋县| 湘阴县| 临夏县| 安徽省| 西贡区| 芜湖县| 河源市|