2013-05-31 57 views
0

我有一個模擬,其中創建圍繞地圖移動。這張地圖是用tkinter繪製的。在模擬的init中,我打電話Python,tkinter沿着邊模擬運行

root = Tk() 
    root.geometry("800x800+300+300") 
    self.ex = land.Example(root) 
    root.mainloop() 

要啓動tkinter,其中land.Example是以下類。應該發生的是最初繪製的地圖,然後模擬運行,任何時候生物移動它將使用self.ex來繪製在tkinter中。問題是,當它運行時,最初繪製地圖,我必須關閉它,以便其餘的模擬將運行。在這種情況下,整個事情就會中斷,因爲模擬試圖使用不存在的畫布。我怎樣才能解決這個問題,從而在地圖和仿真都保持運行

模擬self.ex互動

def move(self, creature, target): 
     self.map[creature.x][creature.y].creatures.remove(creature) 
     self.ex.updateMap(creature.x, creature.y, "remove") 

land.Example

class Example(Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent) 
     self.parent = parent 
     self.parent.title("Board") 
     self.pack(fill=BOTH, expand=1) 
     self.canvas = Canvas(self) 
     self.upperX = 0 
     self.lowerX = 0 
     self.upperY = 0 
     self.lowerY = 0 

     for x, row in enumerate(landMass): 
      for y, cell in enumerate(row): 
       color = "grey" 
       if isinstance(landMass[x][y], Food): 
        color = "green" 
       elif isinstance(landMass[x][y], Water): 
        color = "blue" 
       elif isinstance(landMass[x][y], Shelter): 
        color = "black" 
       self.canvas.create_rectangle(50 * x , 50 * y , 50 * x + 50, 50 * y + 50, 
        outline=color, fill=color) 
       self.canvas.create_text(3 + 50 * x, 3 + 50 * y, anchor=NW, fill="white", text=landMass[x][y].elevation) 
       if color == "green": 
        self.canvas.create_text(3 + 70 * x, 3 + 50 * y, anchor=NE, fill="red", text=landMass[x][y].vegitation) 
       elif color == "black": 
        self.canvas.create_text(3 + 70 * x, 3 + 50 * y, anchor=NE, fill="orange", text=landMass[x][y].quality) 
     self.canvas.pack(fill=BOTH, expand=1) 

    def updateMap(self, x, y, action): 
     color = "grey" 
     if action == "append": 
      #DRAW THE CREATURE AT X,Y 
     elif action == "remove": 
      #DRAW THE ORIGINAL TILE AT X,Y 
     ...   
     self.canvas.pack(fill=BOTH, expand=1) 

編輯:其他企圖

當我添加foll由於仿真的初始化()並添加一個函數。整件事情都在運行,但tk畫布顯示最終結果,而不是結果發生。

 root = Tk() 
     root.geometry("800x800+300+300") 
     self.tkmap = land.Example(root) 
     root.after(2000, self.runSim) 
     root.mainloop() 
    #End of __init__() 

    def runSim(self): 
     for generation in range(self.lifeCycles): 
      self.simulate(generation) 
     return self.evolve() 
+0

看到http://stackoverflow.com/a/459131/ – FabienAndre

+0

與該解決方案的問題是,該任務是遞歸函數,其中因爲我與之合作的是一個班級和對象。 – EasilyBaffled

+0

如果您使用模擬的一個步驟將鏈接答案的'print「hello」'替換掉,就完成了。這個想法不是通過'after'執行一個調用,而是在'調用'之後重複',這樣'Tkinter'可以在兩個步驟之間更新視圖。你可以看到'在'之後*做你的事情,並以x毫秒*喚醒我。如果你不把手放在Tkinter上,視圖不能更新,直到你結束sim。 – FabienAndre

回答

1

在你afterrunSim,你執行你的整個模擬。這個想法是在每次打電話後只做一次(或少數幾次)你的同伴。

這裏是一個小例子它如何工作的:

import random 
from Tkinter import * 

c = Canvas() 
c.pack() 
circle = c.create_oval(100,100,110,110, fill="red") 

def simulate(): 
    #one step of simulation 
    c.move(circle, random.normalvariate(0,3),random.normalvariate(0,3)) 
    c.after(100, simulate) 

c.after(100, simulate) 
c.mainloop() 
+0

那麼在模擬的時候,我可以在if後面添加一個if語句來完成模擬,或者我還需要使用mainloop? – EasilyBaffled

+0

是的,只是沒有調用'之後'就足夠了。您可能只想在離開您的應用程序時離開主循環,可能是在用戶計劃中。如果你想離開代碼,使用'quit'方法。 – FabienAndre