My text in my clock python is not aligning properly

不羁岁月 提交于 2020-06-27 04:08:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!