Tk_watch :horloge graphique

Contenu du snippet

Salut c'est un exercice Graphique/Thread que j'ai fait lorsque j'apprenait à manier le Python depuis j'oublie de le mettre sur la toile juste au cas où. J'espère que les critiques ne seront pas trop rudes. Mais lachez vous quand même.

Source / Exemple :

# coding:latin1
"""gui Watch
##  Programme:  Tk_Watch
##  Version:    1.0
##  Auteur:    afranck64
"""
import tkMessageBox as tk
from Tkinter import *
from threading import Thread
from time import sleep, time
from math import pi, cos, sin, exp
from winsound import Beep

def Rot(x, y, a=0, b=0, ang=1):
    "fait tourner l'objet (x,y) d'un angle <ang> par rapport à (a,b)"
    z = complex(float(x), float(y))
    t = ang*pi/180
    a1 = complex(cos(t),sin(t))
    z0 = complex(a,b)
    z1 = z*a1 + z0*(1-a1)
    return z1.real, z1.imag

class pendule:
    "balançoire pour horloge"
    def __init__(self, boss):
        "contructeur de balançoire"
        self.canev = Canvas(boss, width = 80, height = 120, bg="ivory",bd=2,relief="raised")        #instantiation(création) d'un Canvas
        larg, haut = int(self.canev.cget("width")), int(self.canev.cget("height"))
        self.tige = self.canev.create_line(larg/2+2,5,larg/2+2,haut-5,width = 2)        #dessin et sauvegarde de la tige du pendule
        self.boule = self.canev.create_oval(larg/2+2-3, haut- 5 - 3, larg/2+2+3,haut - 5 + 3,fill = "brown")        #dessin et sauvegarde de la boule du pendule
        self.canev.pack()
        self.cent = larg/2+2,5      #sauvegarde des coordonnées du centre de rotation de laboule
        self.x_b = larg/2+2         #abscisse de la boule du pendule
        self.y_b = haut/2-5         #ordonnée de la boule du pendule

class cani(Canvas):
    "cadrant d'horloge."
    def __init__(self, larg=190,haut=160, coul="ivory",boss=None,one = True):
        "constructeur de notre cadrant"
        Canvas.__init__(self, width=larg, height=haut, bg=coul, master=boss, bd=2, relief="raised")
        x_c,y_c = larg/2+2,haut/2+2
        a,b = x_c, 8
        r = larg/2-8
        self.cent = x_c, y_c            #coordonnées du centre de l'horloge
        self.x_h, self.y_h = x_c,36         #coordonnées de l'aiguille des heures
        self.x_m, self.y_m = x_c, 24        #coordonnées de l'aiguille des minutes
        self.x_s, self.y_s = x_c, 12         #coordonnées de l'aiguille des secondes
        self.create_oval(x_c-r,y_c-r,x_c+r,y_c+r,width=4)       #cercle contenant les aiguilles
        c,d,x,y = x_c,14,x_c,16
        self.one = one
        for i in range(1,61):       #positionnement de points(minutes/secondes)
            c,d = Rot(c,d,x_c,y_c,6)
            x,y = Rot(x,y,x_c,y_c,6)
            self.create_line(c,d,x,y,fill="light green",width = 1.75)
        for i in range(1,13):       #positionnement des heures
            a,b = Rot(a,b,x_c,y_c,30)
            self.create_text(a,b,text=str(i))
        self.H = self.create_line(x_c,y_c,x_c,36,width=4,fill="gold",smooth=1,arrow="last")          #dessin de l'aiguille des heures et sauvegarde
        self.M = self.create_line(x_c,y_c,x_c,24,width=2,fill="red",smooth=1,arrow="last")           #dessin de l'aiguille de minutes et sauvegarde
        self.S = self.create_line(x_c,y_c,x_c,12,smooth=1,arrow="last")           #dessin de l'aiguille des secondes et sauvegarde
        

#routine permetant de faire évoluer les aiguilles et le pendule
class Trd(Thread):
    "Processus qui permet de mettre en marche les différentes animations"
    def __init__(self,can=None):
        Thread.__init__(self)
        self.a = 1
        self.can = can
        
    def do(self):
        self.a = 1
        
    def run(self):
        "fonction principale du processus"
        while self.a == 1:
            sleep(.05)
            cent = self.can.cent
            a,b = cent
            #juste au cas où il y aurait un problème quelconque:
            try:
                x_h,y_h = self.can.x_h,self.can.y_h
                x_m,y_m = self.can.x_m,self.can.y_m
                x_s,y_s = self.can.x_s,self.can.y_s
            except:
                self.a = None
            if value.get() == True:         #si la case continue est cochée, on prend en compte les virgules
                tmp = time()
            else:       #si la case trotte est cochée, on ne compte que les entiers
                tmp = int(time())
            c_x, c_y = pend.cent
            x_b = pend.x_b
            y_b = pend.y_b
            ang = (30*pi/360)*sin(pi*(time() + .5))
            Long = 110
            x_t = (Long*sin(30*pi/360)*sin(pi*(time() + .5))+c_x)      #calcul de l'abcisse de la boule du pendule
            y_t = Long*cos(ang)+c_y         #calcul de l'ordonnée de la boule du pendule
            if son.get() == True:       #vérifie si la case <sound on> est cochée
                if abs(x_t) > Long*sin(29.85*pi/360) + c_x:      #si le pendule atteint une de ses positions extrêmes alors "ding"
                    Beep(564,50)
                    pend.canev.configure(bg="grey95")
                if x_t < c_x-Long*sin(29.85*pi/360):         #si le pendule atteint l'autre de ses positions extrêmes alors "dong"
                    Beep(356,50)
                    pend.canev.configure(bg="grey90")
            pend.canev.coords(pend.tige,c_x,c_y,x_t,y_t)        #repositionnement de la tige du pendule
            pend.canev.coords(pend.boule,x_t-3,y_t-3,x_t+3,y_t+3)       #repositionnement de la boule du pendule
            #calculs des heures,minutes et secondes en fonction du temps revenvoyé par la machine
            t = tmp
            sec = t
            secs = sec%60
            Min = (tmp)/60
            mins = Min%60
            heur = (tmp-secs)/(3600)
            heurs = heur%60 + 2 #le 2 c'est pour le décalage horaire de ma montre j'ai pas trouvé mieux
            #calculs des angle que doivent faire les aiguilles des heures, minutes et secondes avec l'axe des abcsisses
            ang_h = heurs*30
            ang_m = Min*6
            ang_s = secs*6
            #détermination des coordonnées des aiguilles en fonction de ces aiguilles
            x_h,y_h = Rot(x_h,y_h,a,b,ang_h)
            x_m,y_m = Rot(x_m,y_m,a,b,ang_m)
            x_s,y_s = Rot(x_s,y_s,a,b,ang_s)
            #repositionnnement des aiguilles
            try:
                self.can.coords(self.can.H,a,b,x_h,y_h)
                self.can.coords(self.can.M,a,b,x_m,y_m)
                self.can.coords(self.can.S,a,b,x_s,y_s)
                root.update()
            except:
                self.a = None
                self.stop(None)
                
    def stop(self,event):
        "fonction qui stoppe ce procesus"
        self.a = None
        

### code de test:###
if __name__ == "__main__":
    root = Tk()
    root.title("spy_horloge")
    root.overrideredirect(1)
    root.resizable(False,False)
    frm = Frame(root, bd=2,relief="raised")
    frm2 = Frame(root,bd=2,relief="sunken")
    me = cani(boss = frm)
    me.pack(side="top")
    frm.pack()
    frm2.pack()
    pend = pendule(frm)
    t = Trd(me)
    son = BooleanVar(root,False)
    chk = Checkbutton(frm2, text = "sound on",variable = son)
    chk.pack(side="top")
    value = BooleanVar(root,True)
    c = Radiobutton(frm2,text = "continue",value = True,variable=value)
    c.pack(side="left")
    trot = Radiobutton(frm2,text = "trotte",value = False,variable=value)
    trot.pack(side="right")
    
    def play():
        caption = btn1.cget("text")
        if caption == "Start":
            btn1.configure(text="Stop")
            t.do()
            t.run()
        else:
            btn1.configure(text="Start")
            t.stop(None)
            
    btn1 = Button(root,text="Start",command=play,bg="grey70")
    btn1.pack(side="left",pady=5,padx=2)
    Button(root,text="Exit",command=root.destroy,bg="grey65").pack(side="right",pady=5,padx=2)
    root.bind("<Destroy>",t.stop)
    tk.Message(title = "About",message = "Ecrit par spy_anfnThanks to Gerard Swinnen",master=root).show()
    root.mainloop()

Conclusion :

Bon c'est juste pour aider ceux que je pourrais à manier plus adroitement Tkinter et Python en gros

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.