python tkinter窗口没有响应和挂

时间:2017-08-24 13:26:57

标签: python python-2.7 tkinter tkinter-canvas

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语句,我在主方法中添加了?????

1 个答案:

答案 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.joinjoin方法会让您的主进程等待另一个进程完成,这是您不想要的。

因此,当您按下按钮时,将调用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窗口,而且整个系统:) 因为无论你拥有多少内存,这个过程都会无休止地分叉,消耗你拥有的所有内存。