I am trying to set the starting window for my first turtle script, but after some searching it seems that there is no clean way to do it.
after some searching it seems that there is no clean way to do it
What do you mean by clean? You can set the initial size and starting position of the turtle window using the setup() method:
>>> import turtle
>>> help(turtle.setup)
Help on function setup in module turtle:
setup(width=0.5, height=0.75, startx=None, starty=None)
Set the size and position of the main window.
Arguments:
width: as integer a size in pixels, as float a fraction of the
Default is 50% of
height: as integer the height in pixels, as float a fraction of the
Default is 75% of
startx: if positive, starting position in pixels from the left
edge of the screen, if negative from the right edge
Default, startx=None is to center window horizontally.
starty: if positive, starting position in pixels from the top
edge of the screen, if negative from the bottom edge
Default, starty=None is to center window vertically.
For example:
from turtle import Screen, Turtle
screen = Screen()
screen.setup(300, 300, startx=100, starty=200)
turtle = Turtle()
turtle.dot(100)
screen.mainloop()
Related
I created a turtle window with python, but I can't make it automatically goes to fullscreen when the program first runs. How to do it? wn.fullScreen()? Thanks for the help!
import turtle
wn=turtle.Screen()
wn.bgcolor("blue")
#wn.fullScreen() ?
import turtle
wn=turtle.Screen()
wn.bgcolor("blue")
wn.setup(width = 1.0, height = 1.0, startx=None, starty=None)
width – if an integer, a size in pixels, if a float, a fraction of the screen; default is 50% of screen
height – if an integer, the height in pixels, if a float, a fraction of the screen; default is 75% of screen
startx – if positive, starting position in pixels from the left edge of the screen, if negative from the right edge, if None, center window horizontally
starty – if positive, starting position in pixels from the top edge of the screen, if negative from the bottom edge, if None, center window vertically
In this simple Python Turtle Graphics example, the furthest position available to click for the right hand-side is 245 and for the bottom of the window -245. For the left and top, -250 and 250 are possible So there are some pixels missing from the right and bottom of the window. Adding 5 to the width and height increases the size in the left and up directions, so doesn't fix the problem.
Can someone explain what is going on here please? Is there a way to specify exact dimensions for the turtle window?
import turtle
def click(x, y):
print(x, y)
screen = turtle.Screen()
screen.setup(500, 500)
screen.onclick(click)
turtle.done()
When we instantiate a turtle object, we can draw a circle. I wonder about the radius parameter of the circle() method.
import turtle
myTurtle = turtle.Turtle()
myTurtle.circle(50)
What is the unit of measurement of this parameter?
Does the radius equal to 50 pixels or 50 inches?
the documentation for turtle.setup indicates that size parameters, if expressed as integers, are pixels, if expressed as floats, are fractions of the screen.
As you can see from the first few lines from the documentation, the forward method uses the unit pixel and since there is no other unit used in the documentation, you can conclude the all methods use pixel.
Edit: After looking at the source code form turtle, I'm on 100% sure that it is using pixel as unit, since it is adding the distance to the position directly.
It depends on whether we're measuring the image on the screen, or a printed PostScript image obtained through the underlying tkinter canvas.
My Dell display has a pixel pitch of 0.282mm so I expect to see 90 dots per inch. If turtle draws a circle with a radius of 45 pixels, what I measure on my screen is a circle with a 1" diameter.
However, if I print that image, and turn off any printing scaling, I won't get a 1" printed circle, but something larger. To achieve a properly printed circle, turtle needs to draw with a radius of 36, as the underlying measure for PostScript conversion seems to be based on points (# 72 per inch):
from turtle import Turtle, Screen
screen = Screen()
screen.setup(400, 600)
tortoise = Turtle()
tortoise.circle(36)
canvas = screen.getcanvas()
canvas.postscript(file="circle.ps")
screen.exitonclick()
Although this circle measures around 3/4" on my screen, the PostScript output on the printer is 1". (Make sure to turn off any automatic scaling features and print # 100%)
The actual size of the image on your monitor depends on its pixel pitch. Although tkinter can work in fixed size points for both display and print, Python turtle only works in variable size pixels for display. Once your determine your monitor's pixel pitch, you can use your own scaling factor, or:
turtle.setworldcoordinates(llx, lly, urx, ury)
to configure your own scaling:
from turtle import Turtle, Screen
PIXEL_PITCH = 0.282 # mm
MM_PER_INCH = 25.4
DOTS_PER_INCH = int(1 / (PIXEL_PITCH / MM_PER_INCH))
screen = Screen()
screen.setup(4 * DOTS_PER_INCH, 5 * DOTS_PER_INCH)
screen.setworldcoordinates(-2, -2.5, 2, 2.5) # convert to inches
tortoise = Turtle()
tortoise.circle(0.5) # 1/2" radius, one inch diameter on my screen
screen.exitonclick()
Which should be reasonably accurate on the screen but not print correctly without extra work to switch units during PostScript conversion or use the correct scaling factor in your print dialog.
Usage of the circle() function:
circle(radius, extent=None, steps=None)
See more here: https://docs.python.org/2/library/turtle.html#turtle.circle
So yes, it is the radius as pixels, the first parameter of the function.
Is it possible to change the position of the turtle console on screen?
My main objective is to write code that can move the window, that's all.
I'm using Python 3.4.0 under Windows 10.
If any extra information is needed please ask.
Why do folks always jump into tkinter before reading the turtle documentation?
Yes, you can set the screen position of the turtle graphics window using the same setup() method you use to size it:
from turtle import Turtle, Screen
def animate():
global offset
screen.setup(width=0.333, height=0.333, startx=offset, starty=offset)
turtle.dot(offset)
offset += 10
if offset < 300:
screen.ontimer(animate, 100)
screen = Screen()
turtle = Turtle()
offset = 30
animate()
screen.exitonclick()
startx, if positive, is the starting position in pixels from the left edge of the screen, or from the right edge if negative. Similarly, starty, if positive, is the starting position from the top edge of the screen, or from the bottom edge if negative. By default, the window is centered on the screen.
Your title asks about the position of the Turtle Graphics window on the screen but the body of your question asks about the Turtle Console. These might be considered two different windows.
My main objective is to write code that can move the window
I can't tell if you just want to set the initial position of the window or actually move the window around the screen so I rewrote my example to demonstrate the later.
Yes. You need to get the root window that contains the Tkinter Canvas that the turtle is using as its TurtleScreen. Once you have that window you can change its geometry.
Here's a simple demo.
import turtle
turtle.setup(width=0.5, height=0.5)
screen = turtle.Screen()
width, height = screen.window_width(), screen.window_height()
canvas = screen.getcanvas()
left, top = 30, 100
geom = '{}x{}+{}+{}'.format(width, height, left, top)
canvas.master.geometry(geom)
t = turtle.Turtle()
turtle.exitonclick()
I need to draw a bar graph using Python's turtle graphics and I figured it would be easier to simply make the pen a thick square so I could draw the bars like that and not have to worry about making dozens of rectangles and filling them in.
When I set the turtle shape using turtle.shape('square') though, it only changes the appearance of the pen but has no effect on the actual drawing:
Is there a way to make turtle actually draw a rectangular stroke, whether that be through built-in methods or through modifying the turtle file?
I DON'T want rounded edges, like this:
To answer the question asked in the title: No, it is not possible to change the pen stroke directly (see cdlane's answer for a possible way to do it by modifying the hardcoded values from tkinter).
I did find a workaround for the use case presented in the question body, however.
A custom pen shape (in this case, representing the exact shape and size of the bar) can be registered like this:
screen.register_shape("bar", ((width / 2, 0), (-width / 2, 0), (-width / 2, height), (width / 2, height)))`
We can then simply loop through each bar, update the pen shape with the new values, and use turtle.stamp to stamp the completed bars onto the graph, no drawing required.
It looks like changing the shape of the pen stroke itself isn't possible. turtle.shape('square') only changes the shape of the turtle, not the pen stroke. I suggest lowering the pen size, and creating a function to draw a rectangle. You could use this do draw the bars.
I've two solutions to this problem that I've used in various programs.
The first is a variation on your stamp solution. Rather than use screen.register_shape() to register a custom polygon for each line, use a square turtle and for each line turtle.turtlesize() it into the rectangle you want to stamp:
from turtle import Turtle, Screen
STAMP_SIZE = 20 # size of the square turtle shape
WIDTH, LENGTH = 25, 125
yertle = Turtle(shape="square")
yertle.penup()
yertle.turtlesize(WIDTH / STAMP_SIZE, LENGTH / STAMP_SIZE)
yertle.goto(100 + LENGTH//2, 100) # stamps are centered, so adjust X
yertle.stamp()
screen = Screen()
screen.exitonclick()
My other solution, when I need to draw instead of stamp, is to reach into turtle's tkinter underpinning and modify turtle's hardcoded line end shape itself:
from turtle import Turtle, Screen
import tkinter as _
_.ROUND = _.BUTT
WIDTH, LENGTH = 25, 125
yertle = Turtle()
yertle.width(WIDTH)
yertle.penup()
yertle.goto(100, 100)
yertle.pendown()
yertle.forward(LENGTH)
screen = Screen()
screen.exitonclick()
Use multiple stamps like so:
import turtle
turtle.shape("square")
for count in range(x):
turtle.stamp()
turtle.forward(1)