Tkinter画布没有更新

时间:2017-01-05 17:41:23

标签: python python-3.x canvas tkinter tkinter-canvas

我试图创建一个程序,动物在一个环境中随机移动,存储在一个数组中。我也试图在tkinter画布上以图形方式表示这一点,但画布只是显示什么。根据我的阅读,似乎我可以使用'之后'解决这个问题的方法但是我不知道如何将它集成到我的程序中。

任何帮助都将不胜感激。

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

2 个答案:

答案 0 :(得分:0)

考虑条件:

if random.randint(0,10) == 5 and self.template == "N":

由于self.template是嵌套列表,因此永远不会为True,我想您要检查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

所以这是进步,但你仍然有一些工作来修复你的代码。

答案 1 :(得分:0)

另一种方法是使用

root.update_idletasks()
root.update()
time.sleep(0.05) #the actual number doesn't matter

代替mainloop,将这两个放在while循环中,如下所示:

while True:
    #all your running functions here
    #the code above

然后应该可以更新