Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Python: Analoginen kello

aaämdee [18.12.2007 19:03:39]

#

Analoginen kello Tkinterin Canvas-elementillä. Rakenne on pyritty pitämään yksinkertaisena. Ohjelman pitäisi toimia pythonin perusmoduuleilla (Tkinter, math ja time). Kommentit kertovat koodin toiminnasta tarkemmin.

Laittakaa ihmeessä kommenttia, jos keksitte paremman 'koneiston' kellolle. :)

(2021: moderaattori lisäsi Python 3 -tuen.)

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
	from Tkinter import *
else:
	from tkinter import *

import math
import time

class Kello:
    #__init__ suoritetaan olion luonnissa
    def __init__(self, root, koko=500, tausta="#dddddd",
                 vari_s="red", vari_m="green", vari_h="blue",
                 vari_num="black"):

        #Keskuspisteen koordinaatit.
        self.x1 = self.y1 = koko/2
        self.koko = koko

        #sekunnit, minuutit ja tunnit.
        self.ss = 0
        self.mm = 0
        self.hh = 0

        #Odotettava aika seuraavaan viisarinliikautukseen
        self.odotus = 1000

        #Luoaan Canvas elementti
        self.c = Canvas(root, bg=tausta, height=koko, width=koko)

        #Luodaan viisarit
        self.sekunnit = self.c.create_line(0,0,1,0,fill=vari_s,smooth="true")
        self.minuutit = self.c.create_line(0,0,1,0,fill=vari_m,smooth="true")
        self.tunnit = self.c.create_line(0,0,1,0,fill=vari_h,smooth="true")

        #Luodaan kellotaulun numerot
        for i in range(12):
            if i == 0:
                teksti = "12"
            else:
                teksti = str(i)
            #Käytetään koordinaatit-funktiota. Palautuksesta halutaan
            #vain 2 jälkimmäistä (keskuspistettä ei tarvita)
            self.c.create_text(self.koordinaatit(koko/2.1,i*30)[2:],
                               text=teksti, fill=vari_num)

        #Tehdään osista näkyviä
        self.c.pack()

        #Haetaan aika käyttöjärjestelmältä
        self.haeAika()

        #Alustetaan ajastin, jota tarvitaan seuraavan odotusajan laskemiseen
        self.ajastin = int(time.time())
        #Käynnistetään kello
        self.kaynnista()

    def kaynnista(self):

        #Odotusaika seuraavaan viisarinsiirtoon lasketaan tässä
        self.odotus = int(1000 - (time.time() - self.ajastin)*1000)
        #Odotusaika pitää laskea, koska odottamalla aina 1000ms kello
        #alkaa jätättää.

        #Tietyn ajan kuluttua suoritetaan käynnistä-funktio uudelleen
        #Tähän käytetään Canvaksen after -funktiota
        self.c.after(self.odotus,self.kaynnista)

        self.ajastin += 1

        #Lasketaan uudet koordinaatit viisareille. Tunneille ja minuuteille
        #lisätään vielä osittaiset viisarinliikkeet
        self.c.coords(self.sekunnit,
                      self.koordinaatit(self.koko/2.0,self.ss*6))
        self.c.coords(self.minuutit,
                      self.koordinaatit(self.koko/2.2,self.mm*6+self.ss/10.0))
        self.c.coords(self.tunnit,
                      self.koordinaatit(self.koko/3.0,self.hh*30+self.mm/2.0))
        self.ss += 1

        #Kellon mekanismi
        if self.ss > 59:
            self.ss = 0
            self.mm += 1
            if self.mm > 59:
                self.mm = 0
                self.hh += 1
                if self.hh > 11:
                    self.hh = 0

    #Tämä funktio laskee koordinaatit viisarille
    def koordinaatit(self, pituus, kulma):
        #Lasketaan trigonometrian avulla 'delta X' ja 'delta Y'
        dy = int(abs(math.sin(math.radians(kulma+90)) * (pituus)))
        dx = int(abs(math.cos(math.radians(kulma+90)) * (pituus)))

        #Lasketaan neljäsosaympyröille koordinaatit erikseen
        if kulma < 90:
            x2 = self.x1 + dx
            y2 = self.y1 - dy
        elif kulma < 180:
            x2 = self.x1 + dx
            y2 = self.y1 + dy
        elif kulma < 270:
            x2 = self.x1 - dx
            y2 = self.y1 + dy
        else:
            x2 = self.x1 - dx
            y2 = self.y1 - dy
        #Palautetaan lasketut arvot tuple tyyppisenä
        return (self.x1,self.y1,int(x2),int(y2))

    #Ajan hakemis -funktio
    def haeAika(self):
        #Tällä saa vuodet, päivät, tunnit, jne... taulukkoon.
        t = time.localtime(time.time())
        #Vain tunnit, minuutit ja sekunnit kiinnostavat.
        t = t[3:6]
        #Asetetaan saadut ajat Kelloon.
        self.hh = t[0]
        self.mm = t[1]
        self.ss = t[2]
        #Tunteja ei saa olla 12 tai enemmän.
        while self.hh > 11:
            self.hh -= 12

#Yleensä ikkuna nimetään 'root'
root = Tk()

#Luodaan kello
kello = Kello(root)

#Main Loop
root.mainloop()

lexathedj [28.10.2018 09:24:27]

#

et muistanut laittaa tkinter tekstin alkukirjaimen pieneksi.

# ei hyväksy koska Tkinter sanassa on iso alkukirjain.
from Tkinter import *
# nyt se hyvaksyy koska tkinter sanassa on pieni alku kirjain.
from tkinter import *

abcabc [14.10.2021 15:20:11]

#

Python2ssa on Tkinter isolla.

# python2
from Tkinter import *

olisi sama kuin

# python3
from tkinter import *

dokumentaatio

peran [14.10.2021 17:05:42]

#

aaämdee kirjoitti:

# -*- coding: cp1252 -*-
from Tkinter import *

???

Eikös olla jo päästy kivikaudesta, niin miksi et käytä utf-8:aa ja python3:sta?

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from tkinter import *

Muuten ihan kiva pikku ohjelma.

Edit - Julkaisu olikin kivikaudelta, mutta noi muutokset voisi päivittää koodivinkkiin.

jalski [14.10.2021 19:16:07]

#

peran kirjoitti:

(14.10.2021 17:05:42): ”– –” ??? Eikös olla jo päästy...

Itse vaan ihmettelen miksi laskea mitään odotusaikaa viisarin siirtoon? Miksei vaan suoraan piirrä viisareille sitä tilaa minkä saa kun hakee järjestelmän kellonajan sekunnin välein?

Metabolix [14.10.2021 19:19:55]

#

Lisäsin koodiin Python 3 -tuen. Alkuperäinen tekijä tuskin on nyt koodia korjailemassa, kun koodi on 14 vuotta vanha ja tekijä ei ole edes kirjautunut kahdeksaan vuoteen. Voi miettiä, kannattaako kovin aktiivisesti kommentoida näin vanhoja koodeja vai voisiko mieluummin tuottaa jotain ihan uutta sisältöä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta