【问题标题】:Tkinter UI Becomes Unresponsive While For Loop Is RunningFor 循环运行时,Tkinter UI 变得无响应
【发布时间】:2019-04-09 16:17:16
【问题描述】:

我遇到了一个问题,我的 Tkinter UI 在运行 for loop 时完全卡住且无法交互。我的示例代码在循环中打印“循环”,并且 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 函数创建一个新线程,但这不起作用。

更新的代码,UI 是响应式的,但按下取消时没有任何反应:

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()

【问题讨论】:

  • 添加线程不起作用怎么办?您是如何尝试的,预期的结果是什么?发生了什么?
  • 我把代码弄乱了,是的,这行得通。现在看来,每次循环运行时我都需要更新“标志”以使其停止。

标签: python multithreading for-loop tkinter


【解决方案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()

【讨论】:

  • 我该如何解决这个问题?我尝试将global flag 放入canc,但这并没有改变任何东西。
  • 很好,没问题
  • 啊,其实我发现这段代码有问题,按取消后就不能再开始循环了。如果这是一个简单的解决方法,您能否更新答案?如果需要时间,请不要打扰。
  • 现在,当单击“开始循环”按钮时,代码会重新开始循环。请参阅上面的更新代码。
  • 非常感谢。
【解决方案2】:

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

我在 thread 中开始了我的耗时工作,并检查了我的线程是否仍在 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 部分很重要,因此线程不会立即调用函数

【讨论】:

    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多