How to draw a clock on python?(one that doesn't have hour hand or minute hand, just a diagram)

Viewed 636

I tried to create a picture of a clock face with python 3 turtle, but the numbers aren't correctly aligned. A little help? Thanks! This is what i have so far:

import turtle

screen=turtle.Screen()
screen.bgcolor(135, 205, 250)

clock = turtle.Turtle()
clock.shape("square")

clock.speed(0)

hours = 6
minutes = 30 

angle = 12

for i in range(angle):
    # draw the leg
    clock.forward(65)
    clock.right(30)
    clock.write(i)

    # go back to the middle and turn back around
    clock.right(180)
    clock.forward(65)
    clock.right(180)
    clock.write(i+1)

clock.shape("circle")
clock.forward(65)

screen.exitonclick()
3 Answers

Your use of bgcolor(135, 205, 250) without first calling colormode(255) makes me suspect you're using a non-standard (Repl) or older version of Python turtle. If so, you should state such to avoid incompatibilities in the answers provided.

Below is how I might go about this problem. The key is to have a sense of the font height so you can make corrections:

from turtle import Screen, Turtle

FONT_SIZE = 12
FONT = ('Arial', FONT_SIZE, 'normal')

RADIUS = 65

screen = Screen()

clock = Turtle()
clock.shape('circle')
clock.speed('fastest')

for hour, angle in enumerate(range(60, -300, -30), start=1):
    clock.setheading(angle)
    position = clock.position()
    clock.forward(RADIUS)
    clock.penup()
    clock.forward(FONT_SIZE)
    clock.sety(clock.ycor() - 2 * FONT_SIZE/3)
    clock.write(hour, align='center', font=FONT)
    clock.setposition(position)
    clock.pendown()

screen.mainloop()

enter image description here

However, using the stated font size is a rough guess and may work poorly on some systems. If this is the case for you, then you can get an accurate value for the font height using the underpinning tkinter function call in this answer My text in my clock python is not aligning properly which I assume you reviewed in your search of SO before posting your own question.

You can control the alignment of the text horizontally in your write() statement with align="center". To align it vertically, you will have to adjust the position with .sety(), accounting for the font's vertical dimension, as shown in the answer to How to center text using "turtle" module in Python

@cdlane has answered correctly - but here is a clock with the date as well.

from turtle import *
from datetime import datetime

def jump(distanz, winkel=0):
    penup()
    right(winkel)
    forward(distanz)
    left(winkel)
    pendown()

def hand(laenge, spitze):
    fd(laenge*1.15)
    rt(90)
    fd(spitze/2.0)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze/2.0)

def make_hand_shape(name, laenge, spitze):
    reset()
    jump(-laenge*0.15)
    begin_poly()
    hand(laenge, spitze)
    end_poly()
    hand_form = get_poly()
    register_shape(name, hand_form)

def clockface(radius):
    reset()
    pensize(7)
    for i in range(60):
        jump(radius)
        if i % 5 == 0:
            fd(25)
            jump(-radius-25)
        else:
            dot(3)
            jump(-radius)
        rt(6)

def setup():
    global second_hand, minute_hand, hour_hand, writer
    mode("logo")
    make_hand_shape("second_hand", 125, 25)
    make_hand_shape("minute_hand",  130, 25)
    make_hand_shape("hour_hand", 90, 25)
    clockface(160)
    second_hand = Turtle()
    second_hand.shape("second_hand")
    second_hand.color("gray20", "gray80")
    minute_hand = Turtle()
    minute_hand.shape("minute_hand")
    minute_hand.color("blue1", "red1")
    hour_hand = Turtle()
    hour_hand.shape("hour_hand")
    hour_hand.color("blue3", "red3")
    for hand in second_hand, minute_hand, hour_hand:
        hand.resizemode("user")
        hand.shapesize(1, 1, 3)
        hand.speed(0)
    ht()
    writer = Turtle()
    #writer.mode("logo")
    writer.ht()
    writer.pu()
    writer.bk(85)

def wochentag(t):
    wochentag = ["Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday", "Sunday"]
    return wochentag[t.weekday()]

def datum(z):
    monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June",
             "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]
    j = z.year
    m = monat[z.month - 1]
    t = z.day
    return "%s %d %d" % (m, t, j)

def tick():
    t = datetime.today()
    sekunde = t.second + t.microsecond*0.000001
    minute = t.minute + sekunde/60.0
    stunde = t.hour + minute/60.0
    try:
        tracer(False)  # Terminator can occur here
        writer.clear()
        writer.home()
        writer.forward(65)
        writer.write(wochentag(t),
                     align="center", font=("Courier", 14, "bold"))
        writer.back(150)
        writer.write(datum(t),
                     align="center", font=("Courier", 14, "bold"))
        writer.forward(85)
        tracer(True)
        second_hand.setheading(6*sekunde)  # or here
        minute_hand.setheading(6*minute)
        hour_hand.setheading(30*stunde)
        tracer(True)
        ontimer(tick, 100)
    except Terminator:
        pass  

def main():
    tracer(False)
    setup()
    tracer(True)
    tick()
    return "EVENTLOOP"

if __name__ == "__main__":
    mode("logo")
    msg = main()
    print(msg)
    mainloop()
Related