0

I am trying to follow this post: Clickable Tkinter labels but I must be misunderstanding the Tkinter widget hierarchy. I am storing an image in a Tkinter.Label, and I would like to detect the location of mouseclicks on this image.

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)           
        self.parent = parent
        ...
        self.image = ImageTk.PhotoImage(image=im)
        self.initUI()


    def initUI(self):
        self.parent.title("Quit button")
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        self.photo_label = Tkinter.Label(self, image=self.image).pack()
        self.bind("<ButtonPress-1>", self.OnMouseDown)
        self.bind("<Button-1>", self.OnMouseDown)
        self.bind("<ButtonRelease-1>", self.OnMouseDown)

#        Tried the following, but it generates an error described below
#        self.photo_label.bind("<ButtonPress-1>", self.OnMouseDown)
#        self.photo_label.bind("<Button-1>", self.OnMouseDown)
#        self.photo_label.bind("<ButtonRelease-1>", self.OnMouseDown)


    def OnMouseDown(self, event):
        x = self.parent.winfo_pointerx()
        y = self.parent.winfo_pointery()
        print "button is being pressed... %s/%s" % (x, y)

When I run the script, my window appears with the desired image, but nothing is printed out, which I take to mean no mouse clicks are detected. I thought this was happening because the individual widget should capture the mouse click, so I tried the commented out block code above:

        self.photo_label.bind("<ButtonPress-1>", self.OnMouseDown)
        self.photo_label.bind("<Button-1>", self.OnMouseDown)
        self.photo_label.bind("<ButtonRelease-1>", self.OnMouseDown)

But this yields the following error:

    self.photo_label.bind("<ButtonPress-1>", self.OnMouseDown)
AttributeError: 'NoneType' object has no attribute 'bind'

Why is Frame and/or Label not showing any signs of detecting mouse clicks? And why is self.photo_label showing up as a NoneType even as the image is in fact displayed, presumably via self.photo_label?

Community
  • 1
  • 1
sunny
  • 3,853
  • 5
  • 32
  • 62

1 Answers1

2

The following:

self.photo_label = Tkinter.Label(self, image=self.image).pack()

Sets your self.photo_label reference to point to whatever was finally returned. Since geometry management methods like pack() return None, that's what self.photo_label points to.

To fix this, do not attempt to chain your geometry management methods onto the widget creation:

self.photo_label = Tkinter.Label(self, image=self.image)
self.photo_label.pack()

self.photo_label now points to a Label object.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • when am I going to learn my lesson about the many class methods that return None?!!? thanks a lot! – sunny Sep 02 '15 at 19:25