Question

The following code is the source code from the tutorial "Thinking in Tkinter".

The file is called tt060.py, a small tutorial on event binding. Below the code is the traceback that I get from IDLE (Py/IDLE ver2.7.3 - Tk ver 8.5). What is wrong with the following code that makes it not run correctly and give an error?

from Tkinter import *

class MyApp:
    def __init__(self, parent):
        self.myParent = parent
        self.myContainer1 = Frame(parent)
        self.myContainer1.pack()

        self.button1 = Button(self.myContainer1)
        self.button1.configure(text="OK", background= "green")
        self.button1.pack(side=LEFT)
        self.button1.bind("<Button-1>", self.button1Click)  #

        self.button2 = Button(self.myContainer1)
        self.button2.configure(text="Cancel", background="red")
        self.button2.pack(side=RIGHT)
        self.button2.bind("<Button-1>", self.button2Click)  #

        def button1Click(self, event):
            if self.button1["background"] == "green":
                self.button1["background"] = "yellow"
            else:
                self.button1["background"] = "green"

        def button2Click(self, event):
            self.myParent.destroy()

root = Tk()
myapp = MyApp(root)
root.mainloop()

Traceback:

Traceback (most recent call last):
  File "C:/Current/MY_PYTHON/ThinkingInTkinter/tt060.py", line 29, in <module>
    myapp = MyApp(root)
  File "C:/Current/MY_PYTHON/ThinkingInTkinter/tt060.py", line 12, in __init__
    self.button1.bind("<Button-1>", self.button1Click)  #
AttributeError: MyApp instance has no attribute 'button1Click'

The first thing I tried, as suggested in the tutorial, was to comment out the root.mainloop() line (no go - I put the line back in). I then removed self. from the event names (lines 12 & 17) to see if that had any effect (nope). I then tried putting the 2 method definitions before the .bind lines to see if that had any effect (nope). I can make it work if I just use the command options, but the tutorial is on event binding, so I'm wondering why the above code will not work?

Was it helpful?

Solution

You have an indentation problem. You need to start each def at the same column:

from Tkinter import *

class MyApp:
    def __init__(self, parent):
        self.myParent = parent
        self.myContainer1 = Frame(parent)
        self.myContainer1.pack()

        self.button1 = Button(self.myContainer1)
        self.button1.configure(text="OK", background= "green")
        self.button1.pack(side=LEFT)
        self.button1.bind("", self.button1Click)  #

        self.button2 = Button(self.myContainer1)
        self.button2.configure(text="Cancel", background="red")
        self.button2.pack(side=RIGHT)
        self.button2.bind("", self.button2Click)  #

    def button1Click(self, event):
        if self.button1["background"] == "green":
           self.button1["background"] = "yellow"
        else:
           self.button1["background"] = "green"

    def button2Click(self, event):
        self.myParent.destroy()

root = Tk()
myapp = MyApp(root)
root.mainloop()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top