问题
My text in my turtle module is not aligning properly, it is aligned up and to the left. I want it to align exactly where the turtle is. Can anyone help? I tried setting the xcor and ycor of the turtle up and to the left by 5 units and that did not work. Any help would be greatly appreciated.
Code:
import time
from datetime import datetime,date
import turtle
t = turtle.Pen()
while True:
turtle.tracer(0, 0)
hour_hand = float(datetime.today().hour)
minute_hand = float(datetime.today().minute)
second_hand = float(datetime.today().second)
# Draw circle
t.hideturtle()
t.circle(150)
t.left(90)
t.up()
t.forward(150)
t.down()
# Draw hands
t.right(float(float(minute_hand) * 6))
t.forward(100)
t.backward(100)
t.left(float(float(minute_hand) * 6))
t.right(int(float(hour_hand) * 30 + float(minute_hand) / 60 * 30))
t.forward(50)
t.backward(50)
t.left(int(float(hour_hand) * 30 + float(minute_hand) / 60 * 30))
t.right(second_hand * 6)
t.forward(125)
t.backward(125)
t.left(second_hand * 6)
# Draw ticks
for x in range(0, 12):
t.up()
t.forward(130)
t.down()
t.forward(20)
t.backward(20)
t.up()
t.backward(130)
t.down()
t.right(30)
for y in range(0, 60):
t.up()
t.forward(140)
t.down()
t.forward(10)
t.backward(10)
t.up()
t.backward(140)
t.down()
t.right(6)
t.up()
# Draw numbers
t.right(32.5)
for z in range(1, 12):
t.forward(130)
t.sety(t.ycor() - 5)
t.setx(t.xcor() - 5)
t.write(z, align = 'center', font = ('Times New Roman', 16))
t.sety(t.ycor() + 5)
t.setx(t.xcor() + 5)
t.backward(130)
t.right(30)
t.forward(130)
t.write(12, align = 'center', font = ('Times New Roman', 16))
turtle.update()
t.hideturtle()
time.sleep(0.85)
t.reset()
I don't really want to use tkinter, it is too complicated.
回答1:
A simpler, though potentially less accurate, way to do this completely within turtle:
FONT_SIZE = 16
FONT = ('Times New Roman', FONT_SIZE)
t.color('red')
t.dot(2) # show target of where we want to center text, for debugging
t.color('black')
t.sety(t.ycor() - FONT_SIZE/2)
t.write(12, align='center', font=FONT)
Now let's address your program as a whole. The primary issues I see is that it flickers and is more complicated than necessary. The first thing to do is to switch turtle into Logo mode, which makes positive angles clockwise and makes 0 degrees at the top (not unlike a clock!).
Then we split the dial drawing onto it's own turtle to be drawn once an we put the hands on their own turtle to be erased and redraw over and over. We all toss the while True:
and sleep()
, which have no place in an event-driven world like turtle, and use a turtle timer event instead:
from datetime import datetime
from turtle import Screen, Turtle
OUTER_RADIUS = 150
LARGE_TICK = 20
SMALL_TICK = 10
FONT_SIZE = 16
FONT = ('Times New Roman', FONT_SIZE)
def draw_dial():
dial = Turtle()
dial.hideturtle()
dial.dot()
dial.up()
dial.forward(OUTER_RADIUS)
dial.right(90)
dial.down()
dial.circle(-OUTER_RADIUS)
dial.up()
dial.left(90)
dial.backward(OUTER_RADIUS)
for mark in range(60):
distance = LARGE_TICK if mark % 5 == 0 else SMALL_TICK
dial.forward(OUTER_RADIUS)
dial.down()
dial.backward(distance)
dial.up()
dial.backward(OUTER_RADIUS - distance)
dial.right(6)
dial.sety(-FONT_SIZE/2)
dial.setheading(30) # starting at 1 o'clock
for z in range(1, 13):
dial.forward(OUTER_RADIUS - (LARGE_TICK + FONT_SIZE/2))
dial.write(z, align='center', font=FONT)
dial.backward(OUTER_RADIUS - (LARGE_TICK + FONT_SIZE/2))
dial.right(30)
def tick():
hour_hand = datetime.today().hour
minute_hand = datetime.today().minute
second_hand = datetime.today().second
hands.reset()
hands.hideturtle() # redo as undone by reset()
hands.right(hour_hand * 30 + minute_hand / 60 * 30)
hands.forward(1/3 * OUTER_RADIUS)
hands.backward(1/3 * OUTER_RADIUS)
hands.left(hour_hand * 30 + minute_hand / 60 * 30)
hands.right(minute_hand * 6)
hands.forward(2/3 * OUTER_RADIUS)
hands.backward(2/3 * OUTER_RADIUS)
hands.left(minute_hand * 6)
hands.right(second_hand * 6)
hands.forward(OUTER_RADIUS - (LARGE_TICK + FONT_SIZE))
hands.backward(OUTER_RADIUS - (LARGE_TICK + FONT_SIZE))
hands.left(second_hand * 6)
screen.update()
screen.ontimer(tick, 1000)
screen = Screen()
screen.mode('logo') # make 0 degrees straight up, positive angles clockwise (like a clock!)
screen.tracer(False)
draw_dial()
hands = Turtle()
tick()
screen.mainloop()
回答2:
I don't really want to use tkinter, it is too complicated.
I don't think it's too complicated and it is the most straight-forward solution to center the text vertically.
Use the following code to get the height of text in your font:
from tkinter import font
t = turtle.Pen()
font_config = font.Font(font=('Times New Roman', 16))
font_height = font_config.metrics("linespace")
Then draw your text using font_height/2
as the vertical offset:
t.sety(t.ycor() - font_height/2)
t.write(z, align="center", font=font_config)
t.sety(t.ycor() + font_height/2)
回答3:
Can someone please explain to me how I could do this in tkinter?
来源:https://stackoverflow.com/questions/62111276/my-text-in-my-clock-python-is-not-aligning-properly