For循环运行时,Tkinter UI变得无响应

时间:2019-04-09 16:17:17

标签: python multithreading for-loop tkinter

我遇到一个问题,当for loop运行时,我的Tkinter UI完全卡住并且不交互。我的示例代码在循环中时打印“循环”,并且UI上有一个“取消”按钮应该停止循环,但是由于我无法单击“取消”按钮,因此无法停止循环。所以我的问题是在循环运行时如何使tkinter UI可用。这是示例代码:

from tkinter import*
import time

root = Tk()

i=10
flag = False

def loop():
    flag = True
    for i in range(100):
        if flag == True:
            time.sleep(0.5)
            print("Looping")


def canc():
    flag = False


btn = Button(root, text="Start Loop", command=loop).pack()
cncl = Button(root, text="Cancel", command=canc).pack()

root.mainloop()

我尝试为loop函数创建一个新线程,但这不起作用。

更新后的代码,用户界面具有响应性,但是当按下取消键时,什么也没有发生:

from tkinter import*
import threading
import time

root = Tk()

i=10
flag = False



def loop():
    flag = True
    for i in range(10):
        if flag == True:
            time.sleep(0.5)
            print("Looping")


def run():
    threading.Thread(target=loop).start()


def canc():
    flag = False


btn = Button(root, text="Start Loop", command=run).pack()
cncl = Button(root, text="Cancel", command=canc).pack()

root.mainloop()

2 个答案:

答案 0 :(得分:1)

'flag'不是全局变量,因此在canc()中将其设置为False时,loop()中'flag'局部变量的值不会更改,因此循环不会停止

还需要root.update()来更新GUI

补救措施:

from tkinter import*
import threading
import time

root = Tk()

def loop():

    global flag
    flag = True

    for i in range(10):
        if flag == True:
            root.update()
            time.sleep(0.5)
            print("Looping")

def canc():
    global flag
    flag = False

btn = Button(root, text="Start Loop", command=loop).pack()
cncl = Button(root, text="Cancel", command=canc).pack()

root.mainloop()

答案 1 :(得分:0)

我找到了解决该问题的方法:

我在线程内开始了我的耗时工作,并检查了我的线程是否仍在 while循环中运行,并且在其中进行了更新我的 Tkinter 根。

这是我的代码:

 def start_axis(input):
    print(input)
    time.sleep(5)

def axis():
    t = threading.Thread(target=start_axis, args=("x"))        
    t.start()

    while t.is_alive():
        try:
            root.update()
        except:
            pass

args部分很重要,因此线程不会立即调用该函数