cs_calogerogigante
Messages postés28Date d'inscriptionjeudi 10 juillet 2003StatutMembreDernière intervention25 octobre 2009 28 janv. 2010 à 13:34
Petite question BUTHON : es-tu sûr d'utiliser les threads correctement ? Car je viens de tester ton programme et mon code simplifié ci-dessus sans invoquer la classe Thread, eh bien, ça marche aussi...
Exemple :
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
from Tkinter import *
import threading
from time import *
import sys
class Application:
def __init__(self):
self.Terminated = False
self.root=Tk()
self.root.title('Barre qui avance avec un thread...')
self.root.geometry('600x160')
self.root.protocol("WM_DELETE_WINDOW", self.finirapplication)
def animate(self):
#Lancement de l'animation
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(500):
if self.Terminated == True:
return
if i >= self.valeur:
self.valeur = i
sleep(0.01)
self.redessiner(i)
self.root.update()
#update du controle
self.valeur = 0
# Lancement programme principal :
if __name__ == "__main__":
app = Application()
Un thread t ne doit-il pas faire appel à la méthode t.run() à un moment donné de son existence ?
cs_calogerogigante
Messages postés28Date d'inscriptionjeudi 10 juillet 2003StatutMembreDernière intervention25 octobre 2009 28 janv. 2010 à 11:55
Salut BOTHAN, merci pour ta correction, il n'y a plus un seul message d'erreur maintenant. Je suis content de ton code car il m'a fourni un superbe exemple simple d'utilisation des Threads avec un graphisme dans le Canvas. J'ai fait un petit travail de simplification de code, pour aller à l'essentiel et comprendre comment fonctionne la manipulation d'une fonction avec un Thread, en m'inspirant à 100% de ton code modifié.
Voici ce que cela donne :
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
from Tkinter import *
import threading
from time import *
import sys
class Application(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.Terminated = False
self.root=Tk()
self.root.title('Barre qui avance avec un thread...')
self.root.geometry('600x160')
self.root.protocol("WM_DELETE_WINDOW", self.finirapplication)
def animate(self):
#Lancement de l'animation
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(500):
if self.Terminated == True:
return
if i >= self.valeur:
self.valeur = i
sleep(0.01)
self.redessiner(i)
self.root.update()
#update du controle
self.valeur = 0
# Lancement programme principal :
if __name__ == "__main__": app Application()
Est-ce que c'est correct, ce que j'ai fait ?
Comment créer un canvas maintenant qui possède plusieurs barres jaunes, chacune manipulées par un thread différent ?
bothan
Messages postés12Date d'inscriptionmercredi 16 juin 2004StatutMembreDernière intervention 3 mai 2010 27 janv. 2010 à 19:42
Salut
stop n'est pas reconnue comme methode et du coup on sort de la boucle et ça m'arrange bien d'ailleurs.
ligne229: mettre un return a la place de stop qui permet de sortir de la boucle de maniere plus correcte
en même temps on peut aussi retirer le 2eme parametre de animate que je n'utilise pas
Bonne soirée
cs_calogerogigante
Messages postés28Date d'inscriptionjeudi 10 juillet 2003StatutMembreDernière intervention25 octobre 2009 27 janv. 2010 à 14:44
Waaaouuuuwwww !!!!
Mille mercis Bothan pour ton ajout qui me ravit, pourquoi ?
Parce que je n'ai pas encore commencé l'étude des threads qui m'intimident un peu...
Ton exemple est donc une superbe opportunité d'approcher le fonctionnement de ces bestioles-là... sur mon propre programme !!! Trop fun !
Juste une petite question : ton code s'exécute très bien sur mon PC, mais j'ai des messages d'erreurs sur la console quand je stoppe ou quand je reprends l'animation...
global name stop is not defined
C'est normal ?
bothan
Messages postés12Date d'inscriptionmercredi 16 juin 2004StatutMembreDernière intervention 3 mai 2010 27 janv. 2010 à 13:17
Bonjour
Bravo pour ce petit code educatif que je me suis permis de completer pour utiliser tes routines de mise a jour des canvas afin de transformer l'application en une animation interactive: en voici le code modifié si cela t'interesse.
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Illustration dynamique des fonctions Sin(x) et Cos(x)
# -----------------------------------------------------------------------------
# Auteurs : Calogero GIGANTE - MRG
# Version python : 2.6.4. avec Tkinter
# Objectif : illustrer dynamiquement le sinus et le cosinus d'un angle en degrés.
# Date : 27 janvier 2010
# Site web : www.gigante.be
# Site python : www.gigante.be/python
# License : GPL
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
from Tkinter import *
import tkMessageBox
import threading
from math import *
from time import *
class Application(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.Terminated = False
self.root=Tk()
self.root.title('Sinus et cosinus - par C. Gigante - Mod MRG')
self.root.geometry('740x720+300+50')
self.u = 24 # unite en px servant à dimensionner TOUS les composants graphiques
self.trait = 2 # épaisseur en px des barres cos et sin
self.nbre_de_pixels_sur_axe_x = self.u * 12
# sur ce nombre de pixels, s'étendent 360 degrés.
self.nbre_pixels_pour_1_deg = float(self.nbre_de_pixels_sur_axe_x)/360
coordspoursin = []
for t in range(0,self.nbre_de_pixels_sur_axe_x,1):
x = t
y = sin ( radians( x / self.nbre_pixels_pour_1_deg ))
xx = 2 * self.u + x
yy = 6 * self.u - (4 * self.u) * y
coordspoursin.append((xx, yy))
coordspourcos = []
# attention, ici, on a tenu compte de l'orientation vers le bas du tracé
# de la fonction cosinus
for t in range(0,self.nbre_de_pixels_sur_axe_x,1):
y = t
x = cos ( radians( y / self.nbre_pixels_pour_1_deg ))
yy = 2 * self.u + y
xx = 6 * self.u + (4 * self.u) * x
coordspourcos.append((xx, yy))
# update de l'arc symbolisant l'angle dans le canvas 1
arc_angle = x
if arc_angle == 360:
arc_angle = 359 # ceci est fait pour éviter la disparition de l'arc quand l'angle atteint 360 deg.
self.c1.itemconfigure("arc1",extent=arc_angle)
# update de la boule 1 (et du rayon) :
x = self.c1_x0 + nouv_cos * 4 * self.u
y = self.c1_y0 - nouv_sin * 4 * self.u
self.c1.coords("rayon", self.c1_x0, self.c1_y0, x, y) # update du rayon
self.c1.coords("boule1", x - 0.2 * self.u, y - 0.2 * self.u, x + 0.2 * self.u, y + 0.2 * self.u)
# update de la barre du sin dans le canvas 1
dx = self.c1_x0 + nouv_cos * 4 * self.u
dy = self.c1_y0 - nouv_sin * 4 * self.u
self.c1.coords("barresinc1", dx, 6 * self.u, dx, dy)
# update de la barre du cos dans le canvas 1
self.c1.coords("barrecosc1", self.c1_x0 , self.c1_y0 - (self.trait/2) , self.c1_x0 + nouv_cos * 4 * self.u, self.c1_y0 - (self.trait/2) )
# update de la barre du sin dans le canvas 2
dx2 = self.c2_x0 + angle * self.nbre_pixels_pour_1_deg
dy2 = self.c2_y0 - nouv_sin * 4 * self.u
self.c2.coords("barresinc2", dx2, 6 * self.u, dx2, dy2)
# update de la boule 2 dans le canvas 2
self.c2.coords("boule2", dx2 - 0.2 * self.u, dy2 - 0.2 * self.u, dx2 + 0.2 * self.u, dy2 + 0.2 * self.u)
# update de la barre du cos dans le canvas 3
dx3 = self.c3_x0 + nouv_cos * 4 * self.u
dy3 = self.c3_y0 + angle * self.nbre_pixels_pour_1_deg
self.c3.coords("barrecosc3", self.c3_x0, dy3, dx3, dy3)
# update de la boule 3 dans le canvas 3
self.c3.coords("boule3", dx3 - 0.2 * self.u, dy3 - 0.2 * self.u, dx3 + 0.2 * self.u, dy3 + 0.2 * self.u)
#Mise a jour des canvas avec un angle donné par le controle :
def redessinertout(self, event=None):
angle = int(self.controle.get())
self.redessiner(angle)
#Lancement de l'animation
def animate(self, y):
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(361):
if self.Terminated == True:
stop
if i >= int(self.controle.get()):
self.controle.set(i)
sleep(0.02)
self.redessiner(i)
self.root.update()
#Affichage MsgBox :
def afficherapropos(self):
tkMessageBox.showinfo(
"A propos de...",
"Sinus et Cosinus\n\n"+
"Un petit programme écrit en Python 2.6 qui\n"+
"utilise Tkinter et qui permet simplement\n"+
"de visualiser dynamiquement le sinus\n"+
"et le cosinus d'un angle en degrés.\n\n"+
"Auteurs : Calogero GIGANTE - MRG - www.gigante.be - 2010")
# Lancement programme principal :
f = Application()
29 juil. 2010 à 22:26
28 juil. 2010 à 14:46
28 juil. 2010 à 14:46
29 janv. 2010 à 09:40
En effet même sans gestion des thread ton programme fonctionne, peut être parce qu'il n'y en a qu'un.
N'étant pas du tout un spécialiste de python et encore moins des threads en python, je ne saurais te dire si ma gestion des threads est correcte.
Cela dit un certain nombre d'ouvrages dont celui de G.Swinnen que tu trouveras ici http://www.inforef.be/swi/download/python_notes.pdf font le point et te seront de meilleur conseil que moi.
Bonne continuation
28 janv. 2010 à 13:34
Exemple :
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
from Tkinter import *
import threading
from time import *
import sys
class Application:
def __init__(self):
self.Terminated = False
self.root=Tk()
self.root.title('Barre qui avance avec un thread...')
self.root.geometry('600x160')
self.root.protocol("WM_DELETE_WINDOW", self.finirapplication)
self.valeur = 1
self.c1 = Canvas(self.root, bg="white")
self.c1.pack(side=LEFT, expand=YES, fill=BOTH)
self.barre = self.c1.create_rectangle( 10, 50, 11, 100, fill="yellow")
#Boutons du 4éme canvas :
bouton_animate = Button(self.root, text="Démarrer", command=self.ianimate)
bouton_stop = Button(self.root, text="Arrêt", command=self.stop)
bouton_reprendre = Button(self.root, text="Reprendre", command=self.reprendre)
bouton_reset = Button(self.root, text="Remise à zéro", command=self.reset)
bouton_animate.pack(side=TOP, expand=YES)
bouton_stop.pack(side=TOP, expand=YES)
bouton_reprendre.pack(side=TOP, expand=YES)
bouton_reset.pack(side=TOP, expand=YES)
self.root.mainloop()
def stop(self):
#Thread Stop :
self.Terminated = True
def redessiner(self,x):
#Mise a jour de la barre :
self.valeur = x
self.c1.coords(self.barre, 10, 50, 10+x, 100)
def redessinertout(self, event=None):
#Mise a jour de la barre avec la valeur donnée par self.valeur :
self.redessiner(self.valeur)
def reset(self, event=None):
if self.Terminated == False:
self.Terminated = True
self.redessiner(1)
def reprendre(self):
#Reprise de l'animation :
self.animate()
def ianimate(self):
#Lancement animation 0-500 :
self.valeur = 0
self.animate()
def animate(self):
#Lancement de l'animation
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(500):
if self.Terminated == True:
return
if i >= self.valeur:
self.valeur = i
sleep(0.01)
self.redessiner(i)
self.root.update()
#update du controle
self.valeur = 0
def finirapplication(self):
self.Terminated = True
self.stop()
sys.exit()
# Lancement programme principal :
if __name__ == "__main__":
app = Application()
Un thread t ne doit-il pas faire appel à la méthode t.run() à un moment donné de son existence ?
28 janv. 2010 à 11:55
Voici ce que cela donne :
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
from Tkinter import *
import threading
from time import *
import sys
class Application(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.Terminated = False
self.root=Tk()
self.root.title('Barre qui avance avec un thread...')
self.root.geometry('600x160')
self.root.protocol("WM_DELETE_WINDOW", self.finirapplication)
self.valeur = 1
self.c1 = Canvas(self.root, bg="white")
self.c1.pack(side=LEFT, expand=YES, fill=BOTH)
self.barre = self.c1.create_rectangle( 10, 50, 510, 100, fill="yellow")
#Boutons du 4éme canvas :
bouton_animate = Button(self.root, text="Démarrer", command=self.ianimate)
bouton_stop = Button(self.root, text="Arrêt", command=self.stop)
bouton_reprendre = Button(self.root, text="Reprendre", command=self.reprendre)
bouton_reset = Button(self.root, text="Remise à zéro", command=self.reset)
bouton_animate.pack(side=TOP, expand=YES)
bouton_stop.pack(side=TOP, expand=YES)
bouton_reprendre.pack(side=TOP, expand=YES)
bouton_reset.pack(side=TOP, expand=YES)
self.root.mainloop()
def stop(self):
#Thread Stop :
self.Terminated = True
def redessiner(self,x):
#Mise a jour de la barre :
self.valeur = x
self.c1.coords(self.barre, 10, 50, 10+x, 100)
def redessinertout(self, event=None):
#Mise a jour de la barre avec la valeur donnée par self.valeur :
self.redessiner(self.valeur)
def reset(self, event=None):
if self.Terminated == False:
self.Terminated = True
self.redessiner(1)
def reprendre(self):
#Reprise de l'animation :
self.animate()
def ianimate(self):
#Lancement animation 0-500 :
self.valeur = 0
self.animate()
def animate(self):
#Lancement de l'animation
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(500):
if self.Terminated == True:
return
if i >= self.valeur:
self.valeur = i
sleep(0.01)
self.redessiner(i)
self.root.update()
#update du controle
self.valeur = 0
def finirapplication(self):
self.Terminated = True
self.stop()
sys.exit()
# Lancement programme principal :
if __name__ == "__main__": app Application()
Est-ce que c'est correct, ce que j'ai fait ?
Comment créer un canvas maintenant qui possède plusieurs barres jaunes, chacune manipulées par un thread différent ?
27 janv. 2010 à 19:42
stop n'est pas reconnue comme methode et du coup on sort de la boucle et ça m'arrange bien d'ailleurs.
ligne229: mettre un return a la place de stop qui permet de sortir de la boucle de maniere plus correcte
en même temps on peut aussi retirer le 2eme parametre de animate que je n'utilise pas
Bonne soirée
27 janv. 2010 à 14:44
Mille mercis Bothan pour ton ajout qui me ravit, pourquoi ?
Parce que je n'ai pas encore commencé l'étude des threads qui m'intimident un peu...
Ton exemple est donc une superbe opportunité d'approcher le fonctionnement de ces bestioles-là... sur mon propre programme !!! Trop fun !
Juste une petite question : ton code s'exécute très bien sur mon PC, mais j'ai des messages d'erreurs sur la console quand je stoppe ou quand je reprends l'animation...
global name stop is not defined
C'est normal ?
27 janv. 2010 à 13:17
Bravo pour ce petit code educatif que je me suis permis de completer pour utiliser tes routines de mise a jour des canvas afin de transformer l'application en une animation interactive: en voici le code modifié si cela t'interesse.
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Illustration dynamique des fonctions Sin(x) et Cos(x)
# -----------------------------------------------------------------------------
# Auteurs : Calogero GIGANTE - MRG
# Version python : 2.6.4. avec Tkinter
# Objectif : illustrer dynamiquement le sinus et le cosinus d'un angle en degrés.
# Date : 27 janvier 2010
# Site web : www.gigante.be
# Site python : www.gigante.be/python
# License : GPL
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
from Tkinter import *
import tkMessageBox
import threading
from math import *
from time import *
class Application(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.Terminated = False
self.root=Tk()
self.root.title('Sinus et cosinus - par C. Gigante - Mod MRG')
self.root.geometry('740x720+300+50')
self.u = 24 # unite en px servant à dimensionner TOUS les composants graphiques
self.trait = 2 # épaisseur en px des barres cos et sin
# création des 4 canvas :
self.c1 = Canvas(self.root, bg="white", width=12*self.u, height=12*self.u)
self.c1.grid(row=0, column=0, padx=0, pady=0)
self.c2 = Canvas(self.root, bg="white", width=17*self.u, height=12*self.u)
self.c2.grid(row=0, column=1, padx=0, pady=0)
self.c3 = Canvas(self.root, bg="white", width=12*self.u, height=17*self.u)
self.c3.grid(row=1, column=0, padx=0, pady=0)
self.c4 = Canvas(self.root, width=17*self.u, height=17*self.u)
self.c4.grid(row=1, column=1, padx=0, pady=0)
self.nbre_de_pixels_sur_axe_x = self.u * 12
# sur ce nombre de pixels, s'étendent 360 degrés.
self.nbre_pixels_pour_1_deg = float(self.nbre_de_pixels_sur_axe_x)/360
coordspoursin = []
for t in range(0,self.nbre_de_pixels_sur_axe_x,1):
x = t
y = sin ( radians( x / self.nbre_pixels_pour_1_deg ))
xx = 2 * self.u + x
yy = 6 * self.u - (4 * self.u) * y
coordspoursin.append((xx, yy))
coordspourcos = []
# attention, ici, on a tenu compte de l'orientation vers le bas du tracé
# de la fonction cosinus
for t in range(0,self.nbre_de_pixels_sur_axe_x,1):
y = t
x = cos ( radians( y / self.nbre_pixels_pour_1_deg ))
yy = 2 * self.u + y
xx = 6 * self.u + (4 * self.u) * x
coordspourcos.append((xx, yy))
# dessins des éléments fixes du 1er canvas :
self.c1.create_line( 6 * self.u, 11 * self.u, 6 * self.u, 1 * self.u, arrow=LAST, tag="c1_axex")
self.c1.create_line( 1 * self.u, 6 * self.u, 11 * self.u, 6 * self.u, arrow=LAST, tag="c1_axey")
self.c1.create_oval( 2 * self.u, 2 * self.u, 10 * self.u, 10 * self.u)
self.c1.create_text( 7 * self.u, 1 * self.u, text="1")
self.c1.create_text( 11 * self.u, 5 * self.u, text="1")
self.c1.create_text( 1 * self.u, 5 * self.u, text="-1")
self.c1.create_text( 5 * self.u, 11 * self.u, text="-1")
self.c1_x0 = 6 * self.u
self.c1_y0 = 6 * self.u
# dessins des éléments mobiles du 1er canvas : self.arc1 self.c1.create_arc( 5 * self.u, 5 * self.u, 7 * self.u, 7 * self.u, start 0, extent = 0, fill="", style=ARC, outline="#EFEFEF", width = 1, tag="arc1")
self.barrecosc1 = self.c1.create_line( self.c1_x0, self.c1_y0 - (self.trait/2), 10 * self.u, 6 * self.u - (self.trait/2), fill="green", width=self.trait, tag="barrecosc1")
# le (- self.trait/2) de self.barrecosc1 sert à décaler légèrement la vue de la barre cosinus de l'axe horizontal
self.barresinc1 = self.c1.create_line( 10 * self.u, 6 * self.u, 10 * self.u, 6 * self.u, fill="red", width=self.trait, tag="barresinc1")
self.rayon = self.c1.create_line( self.c1_x0, self.c1_y0, 10 * self.u, 6 * self.u, tag="rayon")
self.boule1 = self.c1.create_oval( 9.8 * self.u, 5.8 * self.u, 10.2 * self.u, 6.2 * self.u, fill="orange", width=0, tag="boule1")
# dessins des éléments fixes du 2ème canvas :
self.c2.create_line( 1 * self.u, 6 * self.u, 16 * self.u, 6 * self.u, arrow=LAST, tag="c2_axex")
self.c2.create_line( 2 * self.u, 11 * self.u, 2 * self.u, 1 * self.u, arrow=LAST, tag="c2_axey")
self.c2.create_line( 5 * self.u, 5.5 * self.u, 5 * self.u, 6.5 * self.u) # trait x
self.c2.create_line( 8 * self.u, 5.5 * self.u, 8 * self.u, 6.5 * self.u) # trait x
self.c2.create_line( 11 * self.u, 5.5 * self.u, 11 * self.u, 6.5 * self.u) # trait x
self.c2.create_line( 14 * self.u, 5.5 * self.u, 14 * self.u, 6.5 * self.u) # trait x
self.c2.create_line( 1.5 * self.u, 2 * self.u, 2.5 * self.u, 2 * self.u) # trait y
self.c2.create_line( 1.5 * self.u, 10 * self.u, 2.5 * self.u, 10 * self.u) # trait y
self.c2.create_text( 1 * self.u, 2 * self.u, text="1")
self.c2.create_text( 1 * self.u, 10 * self.u, text="-1")
self.c2.create_text( 3 * self.u, 1 * self.u, text="Sin(x)")
self.c2.create_text( 15 * self.u, 5 * self.u, text="x (degré)")
self.c2.create_line( coordspoursin, fill="blue", smooth=1 )
self.c2_x0 = 2 * self.u
self.c2_y0 = 6 * self.u
# dessins des éléments mobiles du 2ème canvas :
self.barresinc2 = self.c2.create_line( 2 * self.u, 6 * self.u, 2 * self.u, 6 * self.u, fill="red", width=self.trait, tag="barresinc2")
self.boule2 = self.c2.create_oval( 1.8 * self.u, 5.8 * self.u, 2.2 * self.u, 6.2 * self.u, fill="orange", width=0, tag="boule2")
# dessins des éléments fixes du 3ème canvas :
self.c3.create_line( 6 * self.u, 1 * self.u, 6 * self.u, 16 * self.u, arrow=LAST, tag="c3_axex")
self.c3.create_line( 1 * self.u, 2 * self.u, 11 * self.u, 2 * self.u, arrow=LAST, tag="c3_axey")
self.c3.create_line( 2 * self.u, 1.5 * self.u, 2 * self.u, 2.5 * self.u) # trait y
self.c3.create_line( 10 * self.u, 1.5 * self.u, 10 * self.u, 2.5 * self.u) # trait y
self.c3.create_line( 5.5 * self.u, 5 * self.u, 6.5 * self.u, 5 * self.u) # trait x
self.c3.create_line( 5.5 * self.u, 8 * self.u, 6.5 * self.u, 8 * self.u) # trait x
self.c3.create_line( 5.5 * self.u, 11 * self.u, 6.5 * self.u, 11 * self.u) # trait x
self.c3.create_line( 5.5 * self.u, 14 * self.u, 6.5 * self.u, 14 * self.u) # trait x
self.c3.create_text( 2 * self.u, 1 * self.u, text="-1")
self.c3.create_text( 10 * self.u, 1 * self.u, text="1")
self.c3.create_text( 7 * self.u, 1 * self.u, text="Cos(x)")
self.c3.create_text( 8 * self.u, 16 * self.u, text="x (degré)")
self.c3.create_line( coordspourcos, fill="blue", smooth=1 )
self.c3_x0 = 6 * self.u
self.c3_y0 = 2 * self.u
# dessins des éléments mobiles du 3ème canvas :
self.barrecosc3 = self.c3.create_line( self.c3_x0, self.c3_y0, self.c3_x0 + 4 * self.u, self.c3_y0, fill="green", width=self.trait, tag="barrecosc3")
self.boule3 = self.c3.create_oval( 9.8 * self.u, 1.8 * self.u, 10.2 * self.u, 2.2 * self.u, fill="orange", width=0, tag="boule3")
# éléments du 4ème canvas : imgsin PhotoImage(file "img_sinus.gif") imgcos PhotoImage(file "img_cosinus.gif")
img1 = Label(self.c4, image=imgsin)
img1.pack(side=TOP) self.controle Scale(self.c4, from_ 0, to = 360, label="Degrés", resolution = 1, tickinterval=45, orient=HORIZONTAL, length = 15*self.u, command = self.redessinertout)
self.controle.pack(side=TOP)
img2 = Label(self.c4, image=imgcos)
img2.pack(side=TOP)
#Spacers pour les boutons du 4éme canvas ::
spcr = Label(self.c4, text=" ")
spcr2 = Label(self.c4, text=" ")
spcr3 = Label(self.c4, text=" ")
#Boutons du 4éme canvas :
bouton_animate = Button(self.c4, text="Animation 0-360", command=self.ianimate)
bouton_stop = Button(self.c4, text="Arret", command=self.stop)
bouton_reprendre =Button(self.c4, text="Reprendre", command=self.reprendre)
bouton_reset = Button(self.c4, text="Remise a 0", command=self.reset)
bouton_apropos = Button(self.c4, text="A propos...", command=self.afficherapropos)
bouton_animate.pack(side=LEFT)
spcr.pack(side=LEFT)
bouton_stop.pack(side=LEFT)
spcr2.pack(side=LEFT)
bouton_reprendre.pack(side=LEFT)
spcr3.pack(side=LEFT)
bouton_reset.pack(side=LEFT)
bouton_apropos.pack(side=RIGHT)
self.root.mainloop()
#Thread Stop :
def stop(self):
self.Terminated = True
#Mise a jour des canvas avec un angle donné :
def redessiner(self,x):
self.controle.set(x)
angle = int(self.controle.get())
nouv_sin = sin(radians(x))
nouv_cos = cos(radians(x))
# update de l'arc symbolisant l'angle dans le canvas 1
arc_angle = x
if arc_angle == 360:
arc_angle = 359 # ceci est fait pour éviter la disparition de l'arc quand l'angle atteint 360 deg.
self.c1.itemconfigure("arc1",extent=arc_angle)
# update de la boule 1 (et du rayon) :
x = self.c1_x0 + nouv_cos * 4 * self.u
y = self.c1_y0 - nouv_sin * 4 * self.u
self.c1.coords("rayon", self.c1_x0, self.c1_y0, x, y) # update du rayon
self.c1.coords("boule1", x - 0.2 * self.u, y - 0.2 * self.u, x + 0.2 * self.u, y + 0.2 * self.u)
# update de la barre du sin dans le canvas 1
dx = self.c1_x0 + nouv_cos * 4 * self.u
dy = self.c1_y0 - nouv_sin * 4 * self.u
self.c1.coords("barresinc1", dx, 6 * self.u, dx, dy)
# update de la barre du cos dans le canvas 1
self.c1.coords("barrecosc1", self.c1_x0 , self.c1_y0 - (self.trait/2) , self.c1_x0 + nouv_cos * 4 * self.u, self.c1_y0 - (self.trait/2) )
# update de la barre du sin dans le canvas 2
dx2 = self.c2_x0 + angle * self.nbre_pixels_pour_1_deg
dy2 = self.c2_y0 - nouv_sin * 4 * self.u
self.c2.coords("barresinc2", dx2, 6 * self.u, dx2, dy2)
# update de la boule 2 dans le canvas 2
self.c2.coords("boule2", dx2 - 0.2 * self.u, dy2 - 0.2 * self.u, dx2 + 0.2 * self.u, dy2 + 0.2 * self.u)
# update de la barre du cos dans le canvas 3
dx3 = self.c3_x0 + nouv_cos * 4 * self.u
dy3 = self.c3_y0 + angle * self.nbre_pixels_pour_1_deg
self.c3.coords("barrecosc3", self.c3_x0, dy3, dx3, dy3)
# update de la boule 3 dans le canvas 3
self.c3.coords("boule3", dx3 - 0.2 * self.u, dy3 - 0.2 * self.u, dx3 + 0.2 * self.u, dy3 + 0.2 * self.u)
#Mise a jour des canvas avec un angle donné par le controle :
def redessinertout(self, event=None):
angle = int(self.controle.get())
self.redessiner(angle)
def reset(self, event=None):
if self.Terminated == False:
self.Terminated = True
self.redessiner(0)
#Reprise de l'animation :
def reprendre(self):
self.animate(self.controle.get())
#Lancement animation 0-360 :
def ianimate(self):
self.controle.set(0)
self.animate(0)
#Lancement de l'animation
def animate(self, y):
if self.Terminated == True:
self.Terminated = False
while not self.Terminated:
for i in range(361):
if self.Terminated == True:
stop
if i >= int(self.controle.get()):
self.controle.set(i)
sleep(0.02)
self.redessiner(i)
self.root.update()
# update de la boule 2 dans le canvas 2
dx2 = self.c2_x0 + 0 * self.nbre_pixels_pour_1_deg
dy2 = self.c2_y0 - sin(radians(0)) * 4 * self.u
self.c2.coords("boule2", dx2 - 0.2 * self.u, dy2 - 0.2 * self.u, dx2 + 0.2 * self.u, dy2 + 0.2 * self.u)
# update de la boule 3 et barre 3 dans le canvas 3
dx3 = self.c3_x0 + cos(radians(0)) * 4 * self.u
dy3 = self.c3_y0 + 0 * self.nbre_pixels_pour_1_deg
self.c3.coords("boule3", dx3 - 0.2 * self.u, dy3 - 0.2 * self.u, dx3 + 0.2 * self.u, dy3 + 0.2 * self.u)
self.c3.coords("barrecosc3", self.c3_x0, dy3, dx3, dy3)
#update du controle
self.controle.set(0)
#Affichage MsgBox :
def afficherapropos(self):
tkMessageBox.showinfo(
"A propos de...",
"Sinus et Cosinus\n\n"+
"Un petit programme écrit en Python 2.6 qui\n"+
"utilise Tkinter et qui permet simplement\n"+
"de visualiser dynamiquement le sinus\n"+
"et le cosinus d'un angle en degrés.\n\n"+
"Auteurs : Calogero GIGANTE - MRG - www.gigante.be - 2010")
# Lancement programme principal :
f = Application()
Pour l'indentation cela a l'air OK.
Bonne continuation