在Tkinter中执行功能期间冻结程序 [英] Program freezing during the execution of a function in Tkinter

查看:122
本文介绍了在Tkinter中执行功能期间冻结程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的一个脚本创建了一个小GUI.一切都很好.

I've created a little GUI for one of my scripts. All is working well.

当我单击一个按钮时,它会启动一个很大的功能,该功能正在解析某些网站上的大量数据.

When I click on one Button, it launches a big function that is parsing a lot of data from some websites.

但是,一旦我单击了Button,程序就会冻结,直到该功能完全运行为止.一切正常,但是为什么我的GUI在执行功能时冻结了. 我想打印一个进度条,但这是不可能的.

But once I've clicked on the Button, the program Freezes until the function is run entirely. All is working fine, but why is my GUI freezing during the execution of the function. I'd like to print a little progress bar, but it's not possible.

这是程序的一部分:

    self.Button1 = Button(self.MENU, text="IELTS", command=self.My_Command)
    self.Button1.grid(row=0, column=0,sticky=W+E)

def My_Command(self):

    ## HERE WE LAUNCH THE FUNCTION
    Module_1.main() # My Big Function from another file

    self.Button1.config(text="DONE")

在执行Module_1.main()期间,我无法执行任何操作//打印任何内容... GUI完全冻结.

I can't do/print anything durint the execution of Module_1.main() ... the GUI is totally freezed.

Module_1.main()函数是一个线程解析器(解析来自两个网站的某些数据),通常需要2分钟才能运行.如果某人有想法可以在执行此功能所需的2分钟内与该程序进行交互,那将非常有帮助.

The Module_1.main() function is a threaded parser (parsing some data from two websites), it takes generally 2 minutes to be ran. If someone have an idea to be able to interact with the program during the 2 minutes needed for the execution of this function, it would be very helpful.

推荐答案

Tkinter是单线程的.屏幕更新会在事件循环中的每次行程中发生.每当您使用长时间运行的命令时,都在阻止事件循环完成迭代,从而阻止了事件的处理,从而阻止了重绘.

Tkinter is single threaded. Screen updates happen on each trip through the event loop. Any time you have a long running command you are preventing the event loop from completing an iteration, thus preventing the processing of events, thus preventing redraws.

您唯一的解决方案是:a)为长时间运行的命令使用线程,b)为长期运行的命令使用进程,或者c)将命令分解为小块,每个小块可以在几毫秒内运行,因此您可以在事件循环的后续迭代中运行一个块.您还有另一种解决方案,该解决方案是定期调用窗口小部件的update_idletasks方法,但这是解决方法,而不是修复方法.

Your only solution is a) use a thread for the long running command, b) use a process for the long running command, or c) break the command up into small chunks that each can be run in a few ms so you can run one chunk during subsequent iterations of the event loop. You have one other solution which is to call the update_idletasks method of a widget periodically, but that's more of a workaround than a fix.

请记住,Tkinter不是线程安全的,因此使用线程需要格外小心.您只能从主线程调用窗口小部件上的方法,这意味着其他线程必须通过线程安全队列与主线程进行通信.

Bear in mind that Tkinter is not thread safe, so using threads requires extra care. You can only call methods on widgets from the main thread, which means other threads must communicate with the main thread via a thread-safe queue.

这篇关于在Tkinter中执行功能期间冻结程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆