为什么这个Tkinter'之后'当我点击停止时循环停止?

时间:2014-12-24 18:42:09

标签: tkinter

何时开始'单击,一个红点从黑色画布的中心生长出来,最终使用after循环包含整个内容。

当我点击停止时,我得到UnboundLocalError: local variable当前referenced before assignment

但我在循环开始之前定义了current - 我迷路了。

我们讨论的最重要的部分是:

Slist = [0, 0, 0, 0, 20]

clicked_stop = BooleanVar()
clicked_stop.set(False)

current = None

def grow():
    if clicked_stop.get() == True:
        biggie.after_cancel(current)
    else:
        Snow = Slist[4]
        Object = vision.create_oval(PlanetLimits(Snow), fill="red")
        Snext = Snow + 20
        Slist.append(Snext)
        Slist.pop(0)
        current = biggie.after(500, grow)

def stop():
    clicked_stop.set(True)

但是为了完全披露,或者如果你想运行代码,我将整个内容包含在内。

import sys
from Tkinter import *

biggie = Tk()
biggie.geometry("1000x900")
biggie.title("Planets")

def PlanetLimits(R):
    return (500-(float(R)/2), 400-(float(R)/2), 500+(float(R)/2), 400+(float(R)/2))

Slist = [0, 0, 0, 0, 20]

clicked_stop = BooleanVar()
clicked_stop.set = False

current = None

def grow():
if clicked_stop.get() == True:
    biggie.after_cancel(current)
else:
    Snow = Slist[4]
    Object = vision.create_oval(PlanetLimits(Snow), fill="red")
    Snext = Snow + 20
    Slist.append(Snext)
    Slist.pop(0)
    #print Snow
    #print clicked_stop
    current = biggie.after(500, grow)
    #print current


def stop():
    clicked_stop.set(True)

vision = Canvas(biggie, height=800, width=1000, bg="black")

vision.grid(row=0, column=0, columnspan = 6)

#resetbutton = Button(biggie, text="Reset", command = Reset).grid(row=1, column=0)
gobutton = Button(biggie, text="Start Simulation", command = grow).grid(row=1, column=1)
stopbutton = Button(biggie, text="Stop Simulation", command = stop).grid(row=1, column=2)
#settingsbutton = Button(biggie, text="Settings", command = Settings).grid(row=1, column=3)
#aboutbutton = Button(biggie, text="About", command = mBox).grid(row=1, column=4)
quitbutton = Button(biggie, text="Quit", command = quit).grid(row=1, column=5)

biggie.mainloop()

2 个答案:

答案 0 :(得分:1)

问题在于这段代码:

current = None

def grow():
    if clicked_stop.get() == True:
        biggie.after_cancel(current)
    else:
        ...
        current = biggie.after(500, grow)

因为您没有将current声明为全局,因此将其设置为grow内的值会变为grow函数的本地值。当if语句的第一部分运行时,因为current是本地的,并且因为你没有在if语句之前将它设置为函数中的任何内容,所以你会得到错误。

如果您打算修改它,则需要将其声明为全局。

答案 1 :(得分:0)

.set()错误地使用BooleanVar,您必须为其赋予TrueFalse的值(不是一个整数,这就是TypeError的原因)被抛出):clicked_stop.set(True)。查看代码,如果您真的要暂停或停止增长,则必须从grow()函数调用stop()。以下是Tkinter中BooleanVar的有用帖子。 Boolean Variable in TKinter 8.5

编辑: 我修复了你的代码,现在它暂停并播放按钮:

import sys
from Tkinter import *

biggie = Tk()
biggie.geometry("1000x900")
biggie.title("Planets")

def PlanetLimits(R):
    return (500-(float(R)/2), 400-(float(R)/2), 500+(float(R)/2), 400+(float(R)/2))

Slist = [0, 0, 0, 0, 20]

clicked_stop = BooleanVar()
clicked_stop.set(False)

current = None

def grow():
    if clicked_stop.get() == 1:
        biggie.after_cancel(0)
    else:
        Snow = Slist[4]
        Object = vision.create_oval(PlanetLimits(Snow), fill="red")
        Snext = Snow + 20
        Slist.append(Snext)
        Slist.pop(0)
##        print Snow
##        print clicked_stop
        current = biggie.after(500, grow)
##        print current

def start():
    clicked_stop.set(False)
    grow()
def stop():
    clicked_stop.set(True)
    grow()

vision = Canvas(biggie, height=500, width=1000, bg="black")

vision.grid(row=0, column=0, columnspan = 6)

#resetbutton = Button(biggie, text="Reset", command = Reset).grid(row=1, column=0)
gobutton = Button(biggie, text="Start Simulation", command = start).grid(row=1, column=1)
stopbutton = Button(biggie, text="Stop Simulation", command = stop).grid(row=1, column=2)
#settingsbutton = Button(biggie, text="Settings", command = Settings).grid(row=1, column=3)
#aboutbutton = Button(biggie, text="About", command = mBox).grid(row=1, column=4)
quitbutton = Button(biggie, text="Quit", command = quit).grid(row=1, column=5)

biggie.mainloop()

您可能需要考虑使用quit函数来调用biggie.destroy(),因为这会在没有来自IDLE的控制台提示的情况下关闭GUI