Nolan Nolan - 9 days ago 5
Python Question

onKey method in turtle module

I copied the following code from my textbook but it will not run. I get the error "builtins.AttributeError: 'Turtle' object has no attribute 'onkey'". I know that the onkey is a methon with the turtle module because it states that it is on the python website. What am I doing wrong here?

import turtle
class Etch:
def __init__(self):
self.myT = turtle.Turtle()
self.myT.color('blue')
self.myT.pensize(2)
self.myT.speed(0)
self.distance = 5
self.turn = 10

self.myT.onkey(self.fwd,'Up')
self.myT.onkey(self.bkwd,'Down')
self.myT.onkey(self.left,'Left')
self.myT.onkey(self.right,'Right')
self.myT.onkey(self.quit,'q')
self.myT.listen()

def fwd(self):
self.myT.forward(self.distance)

def bkwd(self):
self.myT.backward(self.distance)

def left(self):
self.myT.left(self.turn)

def right(self):
self.myT.right(self.turn)

def quit(self):
self.myT.bye()

def main(self):
cTurtle.mainloop()

draw = Etch()
draw.main()


Full traceback
Traceback (most recent call last):
File "/cshome/nbrost/Downloads/etch.py", line 36, in
draw = Etch()
File "/cshome/nbrost/Downloads/etch.py", line 11, in init
self.myT.onKey(self.fwd,'Up')
builtins.AttributeError: 'Turtle' object has no attribute 'onkey'

Answer

Some turtle methods belong to Turtle, some belong to Screen. For beginners, the turtle module tries to hide this distinction. But, for more sophisticated usage, like class methods, it's easy to trip over. I've revised your class to have a Screen member which is used on screen-related methods:

from turtle import Turtle, Screen

class Etch:
    def __init__(self):
        self.myT = Turtle()
        self.myT.color('blue')
        self.myT.pensize(2)
        self.myT.speed(0)
        self.distance = 5
        self.turn = 10

        self.myS = Screen()
        self.myS.onkey(self.fwd,'Up')
        self.myS.onkey(self.bkwd,'Down')
        self.myS.onkey(self.left,'Left')
        self.myS.onkey(self.right,'Right')
        self.myS.onkey(self.quit,'q')
        self.myS.listen()

    def fwd(self):
        self.myT.forward(self.distance)

    def bkwd(self):
        self.myT.backward(self.distance)

    def left(self):
        self.myT.left(self.turn)

    def right(self):
        self.myT.right(self.turn)

    def quit(self):
        self.myS.bye()

    def main(self):
        self.myS.mainloop()

draw = Etch()
draw.main()