The problem is that you don't initialize the active
attribute, so it doesn't exist until the cell becomes active. To fix that, add self.active = False
inside the __init__
method of Buttons
.
You also have a typo in this line (notice you use slef
rather than self
):
self.canvas.itemconfigure(slef.rec, fill = 'black')
Instead of a global binding on the canvas, it would be more efficient to set a binding on each individual rectangle. You can then use the binding to pass the instance of the Buttons
class to the callback. This way you don't have to iterate over several thousand widgets looking for the one that was clicked on.
To do this, use the tag_bind
method of the canvas. You can make it so that your main program passes in a reference to a function to call when the rectangle is clicked, then the binding can call that method and pass it a reference to itself.
For example:
class Buttons:
def __init__(self,canvas,bx,by,tx,ty, callback):
...
self.rec = canvas.create_rectangle(...)
self.canvas.tag_bind(self.rec, "<1>",
lambda event: callback(self))
...
class AppFrame(Frame):
def __init__(...):
...
button = Buttons(..., self.callback)
...
def callback(self, b):
b.activate()