Tkinter canvas 没有更新
Tkinter canvas not updating
我正在尝试创建一个程序,让动物在环境中随机移动,存储在一个数组中。我也试图在 tkinter canvas 上以图形方式表示它,但是 canvas 只是什么都不显示。从我读到的内容来看,我似乎可以使用 'after' 方法来解决这个问题,但是我不知道如何将它集成到我的程序中。
如有任何帮助,我们将不胜感激。
import random
from tkinter import*
class Animal():
def __init__(self,x,y):
self.x = x
self.y = y
class Enviroment():
def __init__(self):
self.GUI = GUIcontainer(self)
self.boardSize = 100
self.template = self.setUpTemplate()
self.GUI.setup()
def setUpTemplate(self):
template = []
for x in range(0,self.boardSize+1):
template.append([])
for y in range(0,self.boardSize+1):
template[x].append("N")
return template
def placeAnimals(self):
print("Placing")
for x in range(0,self.boardSize+1):
for y in range(0,self.boardSize+1):
if random.randint(0,10) == 5 and self.template == "N":
obj = Animal(x,y)
self.template[x][y] = obj
self.GUI.moveOrPlaceObj(obj,x,y)
def moveAnimals(self):
print("Moving")
for x in range(0,self.boardSize+1):
for y in range(0,self.boardSize+1):
if self.template[x][y] != "N":
obj = self.template[x][y]
dirction = random.randint(0,3)
if direction == 0 and y>5:
if self.template[x][y-5] == "N":
self.template[x][y-5] = obj
self.GUI.moveOrPlaceObj(obj,x,y-5)
self.template[x][y] = "N"
elif direction == 1 and x>5:
if self.template[x-5][y] == "N":
self.template[x-5][y] = obj
self.GUI.moveOrPlaceObj(obj,x-5,y)
self.template[x][y] = "N"
elif direction == 2 and y<95:
if self.template[x][y+5] == "N":
self.template[x][y+5] = obj
self.GUI.moveOrPlaceObj(obj,x,y+5)
self.template[x][y] = "N"
elif direction == 3 and x<95:
if self.template[x+5][y] == "N":
self.template[x+5][y] = obj
self.GUI.moveOrPlaceObj(obj,x+5,y)
self.template[x][y] = "N"
class GUIcontainer(object):
def __init__(self,enviro):
self.root = Tk()
self.Enviroment = enviro
self.widgetCreator = GUIwidgetCreator(self.root)
self.entryWidgets = []
self.statLabels = []
self.root.title("Simulation")
def setup(self):
self.widgetCreator.createButton("Start",(lambda event: self.startSim()),2,2)
self.canvas = self.widgetCreator.createCanvas(3,3,100,100,"black")
self.root.mainloop()
def startSim(self):
self.Enviroment.placeAnimals()
self.Enviroment.moveAnimals()
def moveOrPlaceObj(self,obj,x,y):
self.canvas.delete(obj)
self.canvas.create_line(x+0.5,y+0.5,x-0.5,y-0.5,fill="green",tag=obj)
#self.canvas.create_line(x+0.5,y+0.5,x-0.5,y-0.5,fill=obj.colour,tag=obj)
#self.canvas.after(100, self.moveOrPlaceObj)
self.canvas.update_idletasks()
class GUIwidgetCreator(object):
def __init__(self,root):
self.root = root
def createButton(self,txt,cmd,x,y):
self.button = Button(self.root)
self.button.config(text=txt)
self.button.bind("<Button-1>",cmd)
self.button.grid(column=x,row=y)
def createCanvas(self,x,y,height,width,colour):
self.canvas = Canvas(self.root)
self.canvas.config(height=height,width=width)
self.canvas.config(bg=colour)
self.canvas.grid(column=x,row=y)
return self.canvas
if __name__ == "__main__":
program = Enviroment()
考虑条件:
if random.randint(0,10) == 5 and self.template == "N":
因为 self.template
是一个嵌套列表,这永远不会是真的,我想你想改为检查 self.template[x][y]
。
if random.randint(0,10) == 5 and self.template[x][y] == "N":
修改代码后出现错误:
Exception in Tkinter callback
Traceback (most recent call last):
File ".../tkinter/__init__.py", line 1549, in __call__
return self.func(*args)
File ".../test.py", line 75, in <lambda>
self.widgetCreator.createButton("Start",(lambda event: self.startSim()),2,2)
File ".../test.py", line 82, in startSim
self.Enviroment.moveAnimals()
File ".../test.py", line 42, in moveAnimals
if direction == 0 and y>5:
NameError: name 'direction' is not defined
所以这是进步,但您仍然需要做一些工作来修复您的代码。
另一种方法是使用
root.update_idletasks()
root.update()
time.sleep(0.05) #the actual number doesn't matter
代替主循环,将这两个放在 while 循环中:
while True:
#all your running functions here
#the code above
然后它应该更新正常
我正在尝试创建一个程序,让动物在环境中随机移动,存储在一个数组中。我也试图在 tkinter canvas 上以图形方式表示它,但是 canvas 只是什么都不显示。从我读到的内容来看,我似乎可以使用 'after' 方法来解决这个问题,但是我不知道如何将它集成到我的程序中。
如有任何帮助,我们将不胜感激。
import random
from tkinter import*
class Animal():
def __init__(self,x,y):
self.x = x
self.y = y
class Enviroment():
def __init__(self):
self.GUI = GUIcontainer(self)
self.boardSize = 100
self.template = self.setUpTemplate()
self.GUI.setup()
def setUpTemplate(self):
template = []
for x in range(0,self.boardSize+1):
template.append([])
for y in range(0,self.boardSize+1):
template[x].append("N")
return template
def placeAnimals(self):
print("Placing")
for x in range(0,self.boardSize+1):
for y in range(0,self.boardSize+1):
if random.randint(0,10) == 5 and self.template == "N":
obj = Animal(x,y)
self.template[x][y] = obj
self.GUI.moveOrPlaceObj(obj,x,y)
def moveAnimals(self):
print("Moving")
for x in range(0,self.boardSize+1):
for y in range(0,self.boardSize+1):
if self.template[x][y] != "N":
obj = self.template[x][y]
dirction = random.randint(0,3)
if direction == 0 and y>5:
if self.template[x][y-5] == "N":
self.template[x][y-5] = obj
self.GUI.moveOrPlaceObj(obj,x,y-5)
self.template[x][y] = "N"
elif direction == 1 and x>5:
if self.template[x-5][y] == "N":
self.template[x-5][y] = obj
self.GUI.moveOrPlaceObj(obj,x-5,y)
self.template[x][y] = "N"
elif direction == 2 and y<95:
if self.template[x][y+5] == "N":
self.template[x][y+5] = obj
self.GUI.moveOrPlaceObj(obj,x,y+5)
self.template[x][y] = "N"
elif direction == 3 and x<95:
if self.template[x+5][y] == "N":
self.template[x+5][y] = obj
self.GUI.moveOrPlaceObj(obj,x+5,y)
self.template[x][y] = "N"
class GUIcontainer(object):
def __init__(self,enviro):
self.root = Tk()
self.Enviroment = enviro
self.widgetCreator = GUIwidgetCreator(self.root)
self.entryWidgets = []
self.statLabels = []
self.root.title("Simulation")
def setup(self):
self.widgetCreator.createButton("Start",(lambda event: self.startSim()),2,2)
self.canvas = self.widgetCreator.createCanvas(3,3,100,100,"black")
self.root.mainloop()
def startSim(self):
self.Enviroment.placeAnimals()
self.Enviroment.moveAnimals()
def moveOrPlaceObj(self,obj,x,y):
self.canvas.delete(obj)
self.canvas.create_line(x+0.5,y+0.5,x-0.5,y-0.5,fill="green",tag=obj)
#self.canvas.create_line(x+0.5,y+0.5,x-0.5,y-0.5,fill=obj.colour,tag=obj)
#self.canvas.after(100, self.moveOrPlaceObj)
self.canvas.update_idletasks()
class GUIwidgetCreator(object):
def __init__(self,root):
self.root = root
def createButton(self,txt,cmd,x,y):
self.button = Button(self.root)
self.button.config(text=txt)
self.button.bind("<Button-1>",cmd)
self.button.grid(column=x,row=y)
def createCanvas(self,x,y,height,width,colour):
self.canvas = Canvas(self.root)
self.canvas.config(height=height,width=width)
self.canvas.config(bg=colour)
self.canvas.grid(column=x,row=y)
return self.canvas
if __name__ == "__main__":
program = Enviroment()
考虑条件:
if random.randint(0,10) == 5 and self.template == "N":
因为 self.template
是一个嵌套列表,这永远不会是真的,我想你想改为检查 self.template[x][y]
。
if random.randint(0,10) == 5 and self.template[x][y] == "N":
修改代码后出现错误:
Exception in Tkinter callback
Traceback (most recent call last):
File ".../tkinter/__init__.py", line 1549, in __call__
return self.func(*args)
File ".../test.py", line 75, in <lambda>
self.widgetCreator.createButton("Start",(lambda event: self.startSim()),2,2)
File ".../test.py", line 82, in startSim
self.Enviroment.moveAnimals()
File ".../test.py", line 42, in moveAnimals
if direction == 0 and y>5:
NameError: name 'direction' is not defined
所以这是进步,但您仍然需要做一些工作来修复您的代码。
另一种方法是使用
root.update_idletasks()
root.update()
time.sleep(0.05) #the actual number doesn't matter
代替主循环,将这两个放在 while 循环中:
while True:
#all your running functions here
#the code above
然后它应该更新正常