PySimpleGUIQt实现文件下载进度条触发AttributeError问题求助
问题原因
PySimpleGUIQt未实现标准Tkinter版PySimpleGUI提供的write_event_value跨线程通信接口,这是你报错的直接原因。同时你的原代码还存在启动即重复触发下载、小文件下载时chunk_size为0、进度计数可能溢出等潜在问题。
修复后的完整代码
import requests import threading import queue import PySimpleGUIQt as sg from math import floor from tqdm import tqdm # 初始化跨线程通信队列 progress_queue = queue.Queue() header = {"Authorization": "token ghp_*****************************************", "Accept": "application/vnd.github.v4.raw"} link_up = 'https://raw.githubusercontent.com/[user]/[repo]/[branch]/[file name]' def download_file(link, f_name): resp = requests.get(link, headers=header, stream=True) total = int(resp.headers.get('content-length', 0)) # 修复小文件时chunk_size为0的问题,最小设为1 ceil_value = max(floor(total / 100), 1) with open(f_name, 'wb') as file, tqdm(desc=f_name, total=total, unit='iB', unit_scale=True, unit_divisor=ceil_value,) as bar: x_i = 0 for data in resp.iter_content(chunk_size=ceil_value): size = file.write(data) bar.update(size) # 用队列替代write_event_value发进度 progress_queue.put(('Next', min(x_i, 100))) x_i = x_i + 1 # 发送下载完成信号 progress_queue.put(('Finished', None)) sg.theme("DarkBlue") progress_bar = [ [sg.ProgressBar(100, size=(40, 20), pad=(0, 0), key='Progress Bar'), sg.Text(" 0%", size=(4, 1), key='Percent')], ] layout = [ [sg.Button('Download')], [sg.Column(progress_bar, key='Progress')], ] window = sg.Window('Title', layout, size=(520, 80), finalize=True, use_default_focus=False) file_name = 'upload-launcher.exe' # 去掉启动就自动开下载的冗余逻辑,避免未点按钮就开始下载 downloading = False while True: # 给read加100ms超时,定期检查队列消息 event, values = window.read(timeout=100) if event == sg.WINDOW_CLOSED: break if event == 'Download' and not downloading: downloading = True count = 0 window['Progress Bar'].update(current_count=0, max=100) window['Percent'].update(value=f' 0%') thread = threading.Thread(target=download_file, args=(link_up, file_name), daemon=True) thread.start() # 检查队列里的进度消息 while not progress_queue.empty(): msg_type, msg_val = progress_queue.get() if msg_type == 'Next': count = msg_val window['Progress Bar'].update(current_count=count) window['Percent'].update(value=f'{count:>3d}%') elif msg_type == 'Finished': downloading = False print('Download Finished') sg.popup('下载完成', keep_on_top=True) window.close()
核心修改说明
- 用Python标准库
queue.Queue实现跨线程通信,替代PySimpleGUIQt不支持的write_event_value方法 - 给
window.read增加超时参数,定期拉取队列中的进度更新消息 - 增加下载状态锁,避免重复点击下载按钮触发多个下载线程
- 修复小文件场景下
chunk_size为0的异常,进度值做上限限制避免超过100% - 移除程序启动时自动触发下载的冗余逻辑,将下载完成提示移到实际下载结束节点
内容的提问来源于stack exchange,提问作者Ifan_Ifan
相关产品推荐
相关产品推荐

