【问题标题】:Break ongoing loop started by a tkinter button中断由 tkinter 按钮启动的正在进行的循环
【发布时间】:2013-08-03 12:38:22
【问题描述】:

我想构建一个 tkinter 界面,它可以在按下“开始”按钮时开始做一些重复的工作,并在按下“停止”按钮时中断正在进行的循环。但是我注意到 tkinter 不会处理任何进一步的工作,直到正在进行的循环完成,(例如,不响应“停止”按钮单击,不更新文本框或标签文本,如附加代码所示)。从我在 stackoverflow 上读到的内容,这似乎与 tkinter 的单线程性质有关。有人可以帮助一些特定的代码吗?我是 tkinter/Python 的新手,虽然我在船上阅读了许多一般性讨论,但我无法找到真正的解决方案。

import time
import Tkinter as Tk

def _start():
    for outer in range(5):
        if active_stat:
            time.sleep(1) # some code in the real app
        else:
            break
        for inner in range(5):
            if active_stat:
                #counterstr.set("%02d-%02d" % (outer,inner)) #does not update till the end of loop
                textbox.insert(Tk.END, "%02d-%02d\n" % (outer,inner)) #does not show till the end of loop
                print "%02d-%02d" % (outer,inner)
                time.sleep(1) #some code in the real app
            else:
                break

def _stop():
    active_stat=False

active_stat=True

root = Tk.Tk()

#counterstr=Tk.StringVar() 
#Tk.Label(root, textvariable=counterstr).pack(side=Tk.TOP)
textbox=Tk.Text(root) 
textbox.pack(side=Tk.TOP) 
Tk.Button(root, text='Start', command=_start).pack(side=Tk.LEFT)
Tk.Button(root, text='Stop', command=_stop).pack(side=Tk.LEFT)
Tk.Button(root, text='Quit', command=root.quit).pack(side=Tk.LEFT)
root.mainloop()

【问题讨论】:

  • 我不得不为工作做一些类似的事情。如果您愿意,我可以使用 processing 模块发布我的解决方案,以便在单独的进程中运行我的所有代码。

标签: python multithreading loops tkinter break


【解决方案1】:

我要做的是,我会将您的 active_stat 设为 tkinter 变量,然后在您想检查它是否调用它的 get 方法时:

编辑:另外,将root.update() 添加到您的循环中。那应该可以解决您的问题。 tkinter 变量的原因是因为变量范围问题,我最初认为你的问题在哪里。 (注意:此代码适用于 python 3...)

import time
import tkinter as Tk

def _start():
    for outer in range(5):
        if active_stat.get():
            time.sleep(1) # some code in the real app
        else:
            active_stat.set(True)
            break
        for inner in range(5):
            if active_stat.get():
                #counterstr.set("%02d-%02d" % (outer,inner)) #does not update till the end of loop
                textbox.insert(Tk.END, "%02d-%02d\n" % (outer,inner)) #does not show till the end of loop
                print ("{}-{}".format(outer,inner))
                time.sleep(1) #some code in the real app
            else:
                active_stat.set(True)
                break
            root.update()

def _stop():
    active_stat.set(False)


root = Tk.Tk()

active_stat = Tk.BooleanVar(root)
active_stat.set(True)

#counterstr=Tk.StringVar() 
#Tk.Label(root, textvariable=counterstr).pack(side=Tk.TOP)
textbox=Tk.Text(root) 
textbox.pack(side=Tk.TOP) 
Tk.Button(root, text='Start', command=_start).pack(side=Tk.LEFT)
Tk.Button(root, text='Stop', command=_stop).pack(side=Tk.LEFT)
Tk.Button(root, text='Quit', command=root.quit).pack(side=Tk.LEFT)
root.mainloop()

【讨论】:

  • 你的想法不错,但这样行不通。您必须在创建根窗口后创建 BooleanVar。否则,它会爆炸。
  • 致 The-IT 和 iCodez:太棒了!这是我想要的工作。非常感谢。
  • 致 Eric Urban:您好 Eric,我很想看看您是如何使用处理模块的。你能发布你的解决方案吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多