MyButton1 =Button(master, text='Quit',bg="grey",width=20,
command=master.quit)
MyButton1.place(x=200, y=100)
MyButton2 =Button(master, text='Propagate', bg="grey",width=20,
command=mainmethod)
MyButton2.place(x=1000, y=100)
master.geometry("1500x1500")
master.mainloop( )
在上面的代码中按下传播按钮后mainmethod正在调用.. 我在main方法中编写了我的逻辑,其中这个方法单独花费2分钟执行,同时GUI处于无响应状态几分钟,然后在插入的文本框中显示我所需的所有输出
除了使用多线程之外,是否有任何其他方法可以避免无响应的问题并且我看起来按下传播按钮按钮后应禁用,窗口不应该无响应并连续显示text.insert语句,我在主方法中添加了?????
答案 0 :(得分:-1)
为了防止挂起,您需要通过在不同的线程中执行它们来将mainmethod
中的计算与Tkinter的主循环分开。但是,由于GIL(全局解释器锁定),Python中的线程系统并不像其他语言(AFAIK)那样发展得很好,但是有一种替代方法 - 使用与线程类似的进程。 multiprocessing
库可以实现这一点。
为了防止悬挂,你可以创建另一个功能
from multiprocessing import Process
def mainmethodLaunch():
global mainmethodProcess
mainmethodProcess = Process(target=mainmethod)
mainmethodProcess.start()
并将此函数绑定到MyButton2
而不是mainmethod
本身。
文档:https://docs.python.org/2/library/multiprocessing.html#the-process-class
您可以在示例中看到p.join
。 join
方法会让您的主进程等待另一个进程完成,这是您不想要的。
因此,当您按下按钮时,将调用mainmethodLaunch
函数,它将创建另一个执行mainmethod
的进程。 mainmethodLaunch
函数自身的运行持续时间应该是微不足道的。由于使用了另一个进程,Tkinter窗口不会挂起。但是,如果您这样做,您将无法与任何类型的mainmethod
进程进行交互。
为了让这些进程相互通信,您可以使用管道(https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes) 我想这个例子很清楚。
为了随着时间的推移从mainmethod
进程接收一些数据,您必须在一段时间内轮询parent_conn
一次,让我们说,第二次。这可以通过Tkinter的after
方法实现
(tkinter: how to use after method)
重要说明:使用multiprocessing
时,必须在if __name__ == '__main__':
块中初始化程序。我的意思是,在函数和这个块之外应该没有做什么代码,没有做零缩进的代码。
这是因为multiprocessing
将分叉相同的Python可执行文件,它必须区分主进程和分叉进程,而不是在分叉的进程中初始化东西。
如果你这样做,请检查两次,因为如果你犯了这样的错误,它可能会让你不仅要花掉Tkinter窗口,而且整个系统:) 因为无论你拥有多少内存,这个过程都会无休止地分叉,消耗你拥有的所有内存。