Turtle Screen.tracer(0) doesn't stop all animation - python

I thought using Screen.tracer(0) disabled animation in Python Turtle Graphics. However in the following program, if you comment out screen.update(), there is still some animation happening - the turtle trail gets drawn although the turtle doesn't "move" (or get updated). What is happening here please? Is there way to make updating the screen completely manual?
import turtle
def move():
my_turtle.forward(1)
my_turtle.right(1)
screen.update() # Comment out this line to see issue.
screen.ontimer(move, 10)
screen = turtle.Screen()
my_turtle = turtle.Turtle()
my_turtle.shape("turtle")
screen.tracer(0)
move()
turtle.done()

No, screen.tracer(0) doesn't stop all animation. Some turtle commands like end_fill() invoke screen.update() directly, some like dot() invoke it due to other methods that they in turn invoke. You only advise the system when you call update(), not control it completely.
Put your update() calls where you believe you need them, and don't assume certain methods force an update, otherwise future updates of turtle might break your code. (I.e. someone might actually fix turtle.)
For potentially helpful details, see my tracer() rules of thumb and information about the first argument's numeric value

In turtle.py, forward() calls _go() which sets an endpoint, then calls _goto()
_goto() creates a newline if line segments get above 42
if len(self.currentLine) > 42: # 42! answer to the ultimate question
# of life, the universe and everything
self._newLine()
The value appears to be arbitrary; you could set it to something higher, but then there are pauses where nothing appears to be happening.
def _newLine(self, usePos=True):
"""Closes current line item and starts a new one.
Remark: if current line became too long, animation
performance (via _drawline) slowed down considerably.
"""

Related

python turtle graphic doesn't draw

When I run the following code it only pops up a window and doesn't draw any graphic.
I tried a few examples from references but in all cases, it happened. Can someone help me to fix the problem?
import turtle
turtle.mainloop()
t = turtle.Turtle()
t.color('red')
t.pensize(10)
t.shape('turtle')
See here:
https://docs.python.org/3.1/library/turtle.html#turtle.mainloop
Starts event loop - calling Tkinter’s mainloop function. Must be the last statement in a turtle graphics program. Must not be used if a script is run from within IDLE in -n mode (No subprocess) - for interactive use of turtle graphics.
So you have the second line to the end of your program
Also without mainloop i can see an red Turtle drawn when run in repl.it:
https://repl.it/#CarstenEggers/Raphael
The reason it's not doing anything is because you haven't actually told the "draw-er" t to draw anything. All the stuff you've told it to do is just set-up instructions: what color to use, what size to draw at, etc.
Try running this code instead. Explanations in comments:
import turtle
# turtle.mainloop() # Generally not necessary to run mainloop; can just delete
t = turtle.Turtle() # Creating a turtle to do drawing
t.color('red') # Telling it what color to draw
t.pensize(10) # Telling it what size to draw at
t.shape('turtle') # What shape turtle draw-er should be: "arrow", "turtle", etc
# Now let's draw something!
t.forward(50) # Tell turtle to draw in forward direction 50 pixels
t.left(80) # Tell turtle to turn in-place 80 degrees to left
t.forward(100) # Draw 100 pixels forward
t.right(90) # Turn in-place 90 degrees right
t.forward(170) # Draw 170 pixels forward
# Done drawing!
turtle.exitonclick() # Tell program to keep picture on screen, exit on click
# Note: See how that's `turtle` and not `t`? That's because we don't want to
# tell our draw-er `t` anything: `t` is just for drawing, it doesn't control
# the larger scope of starting and exiting. If we said `t.exitonclick()`, the
# program would just break at the end, because the draw-er does not know how
# to exit or anything.
# On the the other hand, the module `turtle` (where we get the draw-er and
# everything else from) does know how to handle starting and exiting, so that's
# why we make the call to the module itself instead of the draw-er `t`.

Re-open turtle after turtle.bye()

I have some code as follows:
# My code here
turtle.bye()
After that, is there any way I can reopen the turtle window.
I know you can do turtle.clearscreen() but that does not close the turtle window.
I will accept any answer which allows me to close the turtle graphics window and then reopen it without opening and running another python program to do this.
Thank you in advance
I've seen situations where the approach of #LukeTimmons worked but not always reliably and not in every situation. Give this solution a try:
import time
import turtle
turtle.dot(200, 'green')
time.sleep(2)
turtle.bye()
# These two lines (indirectly) resurrect turtle environment after turtle.bye()
turtle.Turtle._screen = None # force recreation of singleton Screen object
turtle.TurtleScreen._RUNNING = True # only set upon TurtleScreen() definition
turtle.dot(200, 'red')
turtle.mainloop()
It resets two flags that keep turtle from starting up again. It may be safer to create your own turtle after restart rather than use the default turtle which may point back to the departed environment.
There may be other ways but this is the only way I know.
from turtle import *
def turtle1():
#Your code here
turtle1()
turtle.bye()
turtle1()
This should re-run your code without re-typing it.

turtle onclick() method not working as it should

The following code creates a window in which a python turtle follows wherever your mouse goes. However, it draws indescriminately of whether the user is clicking to draw or not. My code is the following:
Note: You must have pythonwin installed in order for this program to work properly
import turtle, win32api
while True:
# turtle.penup()
user = win32api.GetCursorPos()
mousepos = [user[0]-510,-1*(user[1])+ 410]
turtle.goto(mousepos)
turtle.onclick(turtle.pendown())
In theory, this would only draw when the user is pressing and holding the mouse, but it doesn't work in practice. The commented code will simply cause it to not draw at all. Any advice?
turtle.onclick(turtle.pendown())
Here, you are calling pendown(), which returns probably None; then you're passing this None to onclick(). It probably means "do nothing on a click". That's probably not what you want.
According to #Gibby's comment, you want:
def clicked(*args): # args ignored
turtle.pendown()
turtle.onclick(clicked)

Python turtle.ondrag not working

I've been trying to make a paint program in Python Turtle and for some reason it won't work. I'm using the pen() tool and my code looks like this
from turtle import *
import random
pen()
bgcolor('black')
pencolor('white')
pen.ondrag(pen.goto)
listen()
mainloop()
I've look at this http://docs.python.org/2/library/turtle.html and it says to type turtle.ondrag(turtle.goto) but since I'm using the pen it should work as pen.ondrag but it doesn't, so can someone please clear this up.
Thanks Jellominer
I will simplify and clarify the code given by the questionner:
from turtle import *
ts = Screen(); tu = Turtle()
ts.listen()
ondrag(tu.goto)
mainloop()
This works. You have to click on the turtle and drag it.
First, pen() is not the function you want. Second, although Pen is a synonym for Turtle, pen is not a synonym for turtle. Here's how to go about using ondrag() if you'd like to use Pen instead of Turtle:
from turtle import Pen, Screen, mainloop
def ondrag_handler(x, y):
pen.ondrag(None) # disable handler inside handler
pen.setheading(pen.towards(x, y)) # turn toward cursor
pen.goto(x, y) # move toward cursor
pen.ondrag(ondrag_handler)
screen = Screen()
screen.bgcolor('black')
pen = Pen()
pen.color('white')
pen.shapesize(2) # make it larger so it's easier to drag
pen.ondrag(ondrag_handler)
screen.listen()
mainloop() # screen.mainloop() preferred but not in Python 2
The turtle.ondrag(turtle.goto) makes for a nice short example in the documentation but in reality isn't practical. You want to disable the event handler while handling the event otherwise the events stack up against you. And it's nice to turn the mouse towards your cursor as you drag it.
from turtle import *
ts = Screen()
ondrag(goto)
shapesize(10)
pensize(40)
speed(0)
mainloop()
I think this will surely work.
You can change the size and other things
In here you are using the default turtle .
Sorry but you'll need to take care of the indentation

Turtle in python- Trying to get the turtle to move to the mouse click position and print its coordinates

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.
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)
add – True 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.

Categories