前言
前几天在C站上上看到了类似的博客,回想起了我之前解决这个问题的历程,作为一个自学者&外行,碰到这种问题其实还是挺头疼的。
问题复现
就以之前做的“用起来不一般的word批注整理器”为例(博客路径:【python脚本】word批注批量提取器V2实用版,资源路径:get_word_comments: 用于获取和整理word批注状态的软件,基于python与VBA编码),通过tk搭起来的界面是这样的:
那么在选择目录后,点击“开始检查”,会发生哪些事情呢?
- 递归遍历目录,找出全部的docx文件;
- 选择一个word,后台打开,执行预定好的vba宏代码;
- 选择下一个word打开,直到把所有的word全部执行一遍,得到一众commets.txt;
- python处理所有的commets.txt,收集整理批注;
- 将整理后的信息根据配置写入excel文档;
采用简单的方法组织的话,所有这些操作完成后“开始检查”按键对应的函数才执行结束,这个按键才会弹起来:
button2 = Button(f3, text='开始检查', command=thread_start_check)
而如果文档比较多,处理比较慢时程序就会呈现出卡死的状态,稍有不慎可能就把程序搞死了,所以为了软件的实用性,卡死的问题是必须要解决的。
多线程
作为一个曾经的优秀的验证工程师,对于多线程的使用还是比较熟练的,所以我就明确了解决问题的思路:
python中的线程库为:
import threading
start_check实际的操作为:
def start_check(): update_root() text3.delete("1.0", "end") text3.mark_set('here',1.0) text3.insert('here', "开始检索文件并处理,用时较长请勿退出,请在检查结束后点击 打开结果\n") fullpath = text1.get(1.0, "end").strip() full_docx = get_process_files(fullpath) proc_file(full_docx) log_info_get() gen_excel(mode) text3.mark_set('here',1.0) text3.insert('here', "EXCEL已生成:" + excel_name + "\n") text3.mark_set('here',1.0) text3.insert('here', "==========================================================================\n") pass
那么借助于threading,可以在实际操作外裹一层函数,构成按键实际关联的函数:
def thread_start_check(): t1 = threading.Thread(target=start_check,args=()) t1.start() pass
这样操作后,按键就可以直接回弹,而操作还在继续,log持续打印在显示框中。