5

I'm trying to get the mouse position through Python turtle. Everything works except that I cannot get the turtle to jump to the position of the mouse click.

import turtle

def startmap(): #the next methods pertain to drawing the map
   screen.bgcolor("#101010")
   screen.title("Welcome, Commadore.")
   screen.setup(1000,600,1,-1)
   screen.setworldcoordinates(0,600,1000,0)
   drawcontinents()    #draws a bunch of stuff, works as it should but not really important to the question
   turtle.pu()
   turtle.onclick(turtle.goto)
   print(turtle.xcor(),turtle.ycor())
   screen.listen()

As I understand, the line that says 'turtle.onclick(turtle.goto)' should send the turtle to wherever I click the mouse, but it does not. The print line is a test, but it only ever returns the position that I sent the turtle last, nominally (0, 650) although this does not have major significance.

I tried looking up tutorials and in the pydoc, but so far I have not been able to write this successfully.

I appreciate your help. Thank you.

Edit: I need the turtle to go to the click position(done) but I also need it to print the coordinates.

2rs2ts
  • 10,662
  • 10
  • 51
  • 95
jfa
  • 1,047
  • 3
  • 13
  • 39

1 Answers1

9

You are looking for onscreenclick(). It is a method of TurtleScreen. The onclick() method of a Turtle refers to mouse clicks on the turtle itself. Confusingly, the onclick() method of TurtleScreen is the same thing as its onscreenclick() method.

24.5.4.3. Using screen events

turtle.onclick(fun, btn=1, add=None)
turtle.onscreenclick(fun, btn=1, add=None)

Parameters:

  • fun – a function with two arguments which will be called with the coordinates of the clicked point on the canvas
  • num – number of the mouse-button, defaults to 1 (left mouse button)
  • addTrue or False – if True, a new binding will be added, otherwise it will replace a former binding

Bind fun to mouse-click events on this screen. If fun is None, existing bindings are removed.

Example for a TurtleScreen instance named screen and a Turtle instance named turtle:

>>> screen.onclick(turtle.goto) # Subsequently clicking into the TurtleScreen will
>>>                             # make the turtle move to the clicked point.
>>> screen.onclick(None)        # remove event binding again

Note: This TurtleScreen method is available as a global function only under the name onscreenclick. The global function onclick is another one derived from the Turtle method onclick.

Cutting to the quick...

So, just invoke the method of screen and not turtle. It is as simple as changing it to:

screen.onscreenclick(turtle.goto)

If you had typed turtle.onclick(lambda x, y: fd(100)) (or something like that) you would probably have seen the turtle move forward when you clicked on it. With goto as the fun argument, you would see the turtle go to... its own location.

Printing every time you move

If you want to print every time you move, you should define your own function which will do that as well as tell the turtle to go somewhere. I think this will work because turtle is a singleton.

def gotoandprint(x, y):
    gotoresult = turtle.goto(x, y)
    print(turtle.xcor(), turtle.ycor())
    return gotoresult

screen.onscreenclick(gotoandprint)

If turtle.goto() returns None (I wouldn't know), then you can actually do this:

screen.onscreenclick(lambda x, y: turtle.goto(x, y) or print(turtle.xcor(), turtle.ycor())

Let me know if this works. I don't have tk on my computer so I can't test this.

2rs2ts
  • 10,662
  • 10
  • 51
  • 95
  • Ok, thanks for clearing that up for me. I'm confused as to why the print statement is still not giving me the location of the turtle. I tried putting it in several places. How do I get the location of the turtle that it just moved to? – jfa Jul 25 '13 at 17:59
  • 1
    @Jack You need to print every time you have moved. – 2rs2ts Jul 25 '13 at 18:43
  • Ah thank you, I could not get a separate function working. This does accomplish what I needed for my program. – jfa Jul 25 '13 at 19:12
  • What happens when you make the function call with no arguments, even though the definition calls for arguments in the function? – jfa Jul 25 '13 at 19:15
  • 1
    @Jack I don't know what you mean. The `fun` in `onscreenclick()` must be a function which takes two arguments. Both `gotoandprint()` and that lambda take two arguments. Are you referring to the fact that there are no parentheses after `gotoandprint`? That's because it refers to the function *object*. Parentheses are the syntax for invoking the `__call__` method of objects. Try writing a function in the interactive shell and then typing *just* the function name, without parentheses, and you'll see what I mean. – 2rs2ts Jul 25 '13 at 19:21
  • Ok, I learned later that what I was asking about callback functions. I think I need to learn a bit more about OOP. – jfa Oct 04 '13 at 15:36
  • why is it useful to know the (x, y) coordinates when you click the turtle? isn't that, in effect if not reality, just `turtle.pos()`? – Ryan Oct 30 '18 at 03:56