2013-02-18 76 views
0

我试图在点击它们时将虚线变成实线。相反,我上线时,点击此错误:在类似的问题框架实例没有__call__方法

Traceback (most recent call last): 
    File "/Users/dan/Documents/pyCatan/path_engine.py", line 106, in <module> 
    root.mainloop() 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1017, in mainloop 
    self.tk.mainloop(n) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1414, in __call__ 
    self.widget._report_exception() 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1175, in _report_exception 
    root = self._root() 
AttributeError: Frame instance has no __call__ method 

常见的原因是污染具有多种用途的变量,但我没有这样做,在这里。另外,我已经声明了被调用的方法,这是另一个类似问题中的错误。

这里是我的noobie代码:

from map_gen import MapGen 
from gen_board import CatanApp 
from Tkinter import * 

class PathEngine(object): 
    '''Use the configuration options to show or hide certain attributes.''' 

    # show the edges explicitly 
    SHOW_EDGES = False 
    # show road intersections as nodes, explicitly 
    SHOW_NODES = True 
    # color the hexes to their resource color 
    COLOR_HEXES = False 

    CLICK_ADD_EDGES = True 

    # dimensions 
    HEIGHT = 600 
    WIDTH = 800 

    def __init__(self, root): 
     self._model = MapGen() 
     self._model.gen() 
     CatanApp.set_vertices(self._model.get_map()) 
     self._model.prepare() 
     frame = Frame(root, height=PathEngine.HEIGHT, width=PathEngine.WIDTH) 
     frame.pack() 
     self._canvas = MapDrawer(frame) 
     self.render() 
     self._canvas.config(height=PathEngine.HEIGHT, width=PathEngine.WIDTH) 
     self._canvas.pack() 

    def render(self): 
     if PathEngine.SHOW_NODES: 
      for node in self._model.get_nodes(): 
       self._canvas.draw_node(*node) 
     self.add_edges() 

    def add_edges(self): 
     for edge in self._model.get_roads(): 
      if PathEngine.CLICK_ADD_EDGES: 
       self._canvas.draw_dashed_edge(edge[0][0], edge[0][1], edge[1][0], edge[1][1]) 

class MapDrawer(Canvas): 
    NODE_RADIUS = 20 

    def __init__(self, master): 
     Canvas.__init__(self, master) 
     self._root = master 

    def draw_dashed_edge(self, x1, y1, x2, y2, color=None): 
     if color is None:color = "black" 
     t = "road_%s_%s" % (str((x1, y1)), str((x2, y2))) 
     self.create_line(
      x1, 
      y1, 
      x2, 
      y2, 
      fill=color, 
      dash=(1, 1), 
      width=3, 
      tags=("road", t) 
     ) 
     f = lambda event: self.solidify_dashed_edge(t)     
     self.tag_bind(t, "<Button-1>", f) 

    def solidify_dashed_edge(self, tag): 
     self.itemconfigure(tag, dash=(0, 1)) 

    def draw_node(self, x, y, color=None): 
     if color is None: color = "white" 
     self.create_oval(
      x - MapDrawer.NODE_RADIUS/2, 
      y - MapDrawer.NODE_RADIUS/2, 
      x + MapDrawer.NODE_RADIUS/2, 
      y + MapDrawer.NODE_RADIUS/2, 
      fill=color, 
      outline="black" 
     ) 


if __name__ == "__main__": 
    root = Tk() 
    engine = PathEngine(root) 
    root.mainloop() 
+0

我认为你的缩进是关闭的 - 所有的功能都是类定义之后的类吗? – mgilson 2013-02-18 02:56:50

+0

对不起,我在Python中缩进问题,发布在StackOverflow上... – BlackSheep 2013-02-18 03:02:16

+0

这是一个常见问题。基本上,您可以将它精确地复制粘贴,然后点击看起来像“{}”的小按钮,它总是做正确的事情。 – mgilson 2013-02-18 03:04:43

回答

3

看起来你已经打与添加属性_rootCanvas名称冲突:

>>> import Tkinter as tk 
>>> a = tk.Canvas() 
>>> print a._root 
<bound method Canvas._root of <Tkinter.Canvas instance at 0xee1c0>> 

这是工作的危害之一在没有私人数据的python中:-)。请注意,_rootCanvas对象的一种方法。您覆盖该方法与实例属性:

class MapDrawer(Canvas): 
    NODE_RADIUS = 20 

    def __init__(self, master): 
     Canvas.__init__(self, master) 
     self._root = master 

masterFrame对象。