如何为Tkinter中dataExtraction函数添加自动启停进度条
实现Tkinter进度条显示PDF表格提取进度
先修正原代码中的错误(比如变量名拼写、缺失模块导入、DataFrame合并逻辑),再添加进度条功能,以下是完整可运行的代码:
import camelot import ghostscript import os import pandas as pd import threading from tkinter import * from tkinter import Tk, Canvas, filedialog from tkinter.ttk import Progressbar def dataExtraction(file, progress_bar, root): try: # 阶段1:初始化进度 root.after(0, lambda: progress_bar.config(value=10)) fileName = os.path.basename(file) fileName = fileName.replace('.pdf', "") root.after(0, lambda: progress_bar.config(value=20)) # 阶段2:读取PDF表格 tables = camelot.read_pdf(file, pages='all') root.after(0, lambda: progress_bar.config(value=40)) finalData = pd.DataFrame() total_tables = len(tables) # 阶段3:逐个处理表格,动态更新进度 for idx, table in enumerate(tables): data = table.df finalData = pd.concat([finalData, data], ignore_index=True) # 根据已处理表格数计算进度 current_progress = 40 + (idx + 1) * 50 // total_tables root.after(0, lambda p=current_progress: progress_bar.config(value=p)) # 阶段4:保存Excel文件 finalData.to_excel(f'{fileName}.xlsx', index=False) root.after(0, lambda: progress_bar.config(value=100)) # 完成后1秒隐藏进度条 root.after(1000, lambda: progress_bar.pack_forget()) except Exception as e: print(f"提取出错:{e}") root.after(0, lambda: progress_bar.pack_forget()) def tkWindow(): root = Tk() root.title("PDF表格提取工具") w = root.winfo_screenwidth() h = root.winfo_screenheight() root.geometry(f"{w}x{h}") my_canvas = Canvas(root, width=w, height=h) my_canvas.pack(fill=BOTH, expand=True) pdffile = "" # 存储选中的PDF路径 #### 上传按钮 #### def openPdf(): nonlocal pdffile pdffile = filedialog.askopenfilename(filetypes=[("PDF文件", "*.pdf")]) return pdffile upload = Button(root, width=20, pady=5, text='上传PDF', command=openPdf) pdf_win = my_canvas.create_window(10, 350, anchor='nw', window=upload) #### 进度条 #### progress_bar = Progressbar(root, orient=HORIZONTAL, length=400, mode='determinate') # 初始隐藏进度条 progress_bar.pack(pady=20) progress_bar.pack_forget() # 将进度条放到画布居中位置 progress_win = my_canvas.create_window(w//2 - 200, 400, anchor='nw', window=progress_bar) #### 运行按钮 #### def run(): if not pdffile: return # 未选文件则不执行 # 显示进度条并重置进度 progress_bar.pack() progress_bar.config(value=0) # 启动子线程执行提取任务,避免阻塞UI threading.Thread(target=dataExtraction, args=(pdffile, progress_bar, root), daemon=True).start() runbtn = Button(root, width=10, pady=5, text='开始提取', command=run) run_win = my_canvas.create_window(550, 590, anchor='nw', window=runbtn) root.mainloop() tkWindow()
关键实现说明
- 进度条控制:初始用
pack_forget()隐藏进度条,点击提取按钮时调用pack()显示,任务完成或出错时再次隐藏。 - 跨线程UI更新:Tkinter UI只能在主线程操作,因此用
root.after(0, 回调函数)将进度更新操作投递到主线程队列,避免线程冲突。 - 分阶段进度更新:将提取流程拆分为4个阶段,处理表格时根据已完成数量动态计算进度值,让进度条变化更贴合实际执行过程。
- 异常处理:捕获提取过程中的异常,保证出错时进度条能正常隐藏,避免程序假死。
内容的提问来源于stack exchange,提问作者Raj Banerjee
相关产品推荐
相关产品推荐

