HGI
HGI

Reputation: 83

Python 3 Tkinter canvas

I am trying to draw a clock that works. I am using a 600x600 form. I cant' figure out how to place the oval in the center of the form or how to add the minutes or the seconds tick marks inside the oval. I tried dash but couldn't get it to look right. Any suggestions. Thanks in advance.

This is what I have done so far:

from tkinter import *

canvas_width = 600
canvas_height = 600

master = Tk()

w = Canvas(master, width = canvas_width, height = canvas_height)

w.pack()

oval = w.create_oval(75,75,500,500)
minline = w.create_line(150,150,300,300)

mainloop()

Upvotes: 3

Views: 1284

Answers (1)

Dova
Dova

Reputation: 310

The center of a drawn shape is the middle of the two points specified when it is drawn. Currently, the middle point of your shape (draw from 75, 75 to 500, 500) is 237.5, so, if you want the middle of it to be the middle of your page, and keep the 75, 75 coordinate, you would have to make the other one 525, 525 to completely mirror the first.

As for drawing the shape, you'll need some math in python, so I would first suggest doing an image as the background for the clock, so that less objects are drawn. But, if you must do it without other images, you must first import the math library.

 import math

Now, for a mathematic principle: Any point on the circle of radius r can be expressed as the point (r*cosθ), (r*sinθ), where θ is the angle from the center to the point. The reason this is important is that you want each line on the side of the clock face to be pointing towards the center of the circle. To do that, we need the two points to draw the line on that together point towards the center, and fortunately for us this means that both points on the line are on different circles (our circle and one within it) but are at the same angle from the center.

Since we want 12 hour points around the circle, and 4 minute points between each of those (so 60 points in total), and 360 degrees in a circle (so 1 point for every 6 degrees), we will need a for loop that goes through that.

for angle in range(0, 360, 6):

Then we'll want 3 constants: One for the radius of the exterior circle (for the points to begin from), one for an interior circle (for the minute points to add at), and one for an even more interior circle (for the hour points to end at). We'll also want it to choose the more interior radius only every 30 degrees (because it appears every 5 points, and there are 6 degrees between them).

    radius_out = 225
    radius_in = 0  #temporary value

    if (angle % 30) == 0:  #the % symbol checks for remainder

        radius_in = 210

    else:

        radius_in = 220

Now, for the conversion into radians (As math in python needs radians for sin and cos):

    radians = (angle / 180) * math.pi

Next off, assigning the coordinates to variables so it's easier to read.

    x_out = (radius_out * math.cos(radians)) + 300
    y_out = (radius_out * math.sin(radians)) + 300

    x_in = (radius_in * math.cos(radians)) + 300
    y_in = (radius_in * math.sin(radians)) + 300

    #the (+ 300) moves each point from a relative center of 0,0 to 300,300

And finally we assign it to a list so we can access it later if we need to. Make sure to define this list earlier outside of the for loop.

     coords.append( w.create_line(x_out, y_out, x_in, y_in) )

This should give you your clock lines.

NOTE: Due to the way tkinter assigns x and y coordinates, this will draw lines from the 3 hour line clockwise back to it.

Hope this was helpful! If there is anything you don't understand, comment it below.

Upvotes: 5

Related Questions