如何从internetarchive.upload函数获取已上传字节数?
在PyQt5中实现Archive.org文件上传进度条
我需要将本地文件上传到archive.org,已经用internetarchive模块实现了控制台上传,现在要做PyQt5图形界面简化流程,但缺少进度条体验不好。加verbose=True后控制台会显示tqdm进度条,但无法在GUI中展示,核心需求是获取已上传字节数/文件进度来实现GUI进度条。
尝试的代码
from internetarchive import configure, get_item, upload, get_files from string import ascii_letters, digits from random import choices from time import sleep def get_indentifier(l=20): while 1: identifier = ''.join(choices(ascii_letters + digits, k=l)) if not get_item(identifier).exists: return identifier def upload_callback(*args, **kwargs): print(args, kwargs) configure('email', 'password') print('Logged in') identifier = get_indentifier() print('Uploading...') upload(identifier, ['file-sm.zip'], verbose=True) print('Uploaded') print('Proccessing...') found = False while not found: sleep(5) files = [i for i in get_files(identifier, ['file-sm.zip'])] found = bool(files) print('Done!') print('URL:', files[0].url)
问题
运行后控制台能看到tqdm进度条,但无法将进度数据同步到PyQt5界面。
解决方案
internetarchive的upload函数支持callback参数,可以自定义回调函数获取实时上传进度,结合PyQt5的信号槽机制更新进度条,同时要把上传操作放到子线程避免阻塞GUI。
完整实现代码
from internetarchive import configure, get_item, upload, get_files from string import ascii_letters, digits from random import choices from PyQt5.QtWidgets import (QApplication, QMainWindow, QProgressBar, QPushButton, QVBoxLayout, QWidget) from PyQt5.QtCore import QThread, pyqtSignal import sys from time import sleep def get_identifier(l=20): while True: identifier = ''.join(choices(ascii_letters + digits, k=l)) if not get_item(identifier).exists: return identifier class UploadThread(QThread): # 定义信号:更新进度、上传完成 progress_updated = pyqtSignal(int) upload_finished = pyqtSignal(str) def __init__(self, file_path): super().__init__() self.file_path = file_path self.identifier = get_identifier() def upload_callback(self, chunk_bytes, total_bytes, **kwargs): # 计算进度百分比并发送信号 progress = int((chunk_bytes / total_bytes) * 100) self.progress_updated.emit(progress) def run(self): # 配置登录信息 configure('your_email@example.com', 'your_password') # 上传文件,传入自定义回调 upload(self.identifier, [self.file_path], callback=self.upload_callback) # 等待文件处理完成并获取URL found = False while not found: sleep(5) files = list(get_files(self.identifier, [self.file_path])) found = bool(files) self.upload_finished.emit(files[0].url) class UploadWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("Archive.org 文件上传工具") self.setGeometry(100, 100, 450, 200) # 布局设置 central_widget = QWidget() layout = QVBoxLayout(central_widget) # 进度条 self.progress_bar = QProgressBar() self.progress_bar.setRange(0, 100) layout.addWidget(self.progress_bar) # 上传按钮 self.upload_btn = QPushButton("开始上传") self.upload_btn.clicked.connect(self.start_upload) layout.addWidget(self.upload_btn) self.setCentralWidget(central_widget) self.upload_thread = None def start_upload(self): self.upload_btn.setEnabled(False) self.progress_bar.setValue(0) # 创建并启动上传线程 self.upload_thread = UploadThread('file-sm.zip') self.upload_thread.progress_updated.connect(self.update_progress) self.upload_thread.upload_finished.connect(self.on_upload_done) self.upload_thread.start() def update_progress(self, progress): self.progress_bar.setValue(progress) def on_upload_done(self, url): self.upload_btn.setEnabled(True) print(f"上传完成!文件URL: {url}") if __name__ == "__main__": app = QApplication(sys.argv) window = UploadWindow() window.show() sys.exit(app.exec_())
关键说明
- 回调函数获取进度:
upload_callback会在上传每个数据块后被调用,参数chunk_bytes是已上传总字节,total_bytes是文件总字节,通过这两个值计算进度百分比。 - 子线程处理上传:将上传操作放到
QThread中,避免长时间操作阻塞GUI主线程,保证界面响应。 - 信号槽同步进度:子线程通过
progress_updated信号将进度传递给主线程,主线程更新进度条;上传完成后通过upload_finished信号返回文件URL。
内容的提问来源于stack exchange,提问作者Shahriar
相关产品推荐
相关产品推荐

