IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Modification du diamètre d'un cercle grace a un Scale


Sujet :

Tkinter Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 98
    Points : 57
    Points
    57
    Par défaut Modification du diamètre d'un cercle grace a un Scale
    Bonjour,
    Je bloque depuis un petit moment sur un exercice (gérard swinnen) sur la création d'un canvas avec une balle dedan et un scale qui permette d'en modifier le diamètre.
    le poste l'ébauche de ce que j'ai fait pour le moment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    # Exercice 13.20
    from tkinter import *
     
    # Création du canva
    class Balle(Canvas):
        "Représente une balle dans un canvas"
        def __init__(self, boss=None, larg=200, haut=150, ray=30, coul="red"):
            Canvas.__init__(self)
            self.configure(width=larg, height=haut, bg="dark grey")
            self.larg, self.haut, self.balle = larg, haut, ray
            self.ballon = self.create_oval(self.larg/2-ray,self.haut/2-ray,
                               self.larg/2+ray,self.haut/2+ray, width=2, fill=coul)
     
        def diametre(self, ray=20):
            "Modifie le rayon de la balle"
            self.ballon.itemconfig(self.larg/2-ray,self.haut/2-ray,
                               self.larg/2+ray,self.haut/2+ray)
     
     
    class Regle(Frame):
        "Scale permatant d'effectuer un reglage sur un objet"
        def __init__(self, boss=None):
            Frame.__init__(self)
            self.regl = Scale(self, length=200, orient=VERTICAL, sliderlength=25,
                  label="Taille", from_=20, to=100, tickinterval=2,
                  resolution=5, showvalue=1, command=self.taille)
            self.regl.pack()
     
        def taille(self, regl):
            self.reglage = float(regl)
            self.event_generate("<Control-Z>")
     
    class Fenetre(Frame):
        "Classe regroupant tous les éléments du programme"
        def __init__(self, boss=None):
            Frame.__init__(self)
            fen=Balle(larg=300, haut=300, ray=20)
            fen.pack(padx=10, pady=10, side=LEFT)
            mes = Regle()
            mes.pack()
            Button(text="Quitter", command=self.quit).pack(side=BOTTOM)
            # Désignation de l'evenement qui modifie le diamètre
            self.master.bind("<Control-Z>", self.modif)
     
        def modif(self, event):
            "Modification du diametre de la balle"
            self.fen.diametre(mes.taille.reglage)
     
     
    Fenetre().mainloop()
    Je n'arrive pas a attribuer correctement le diamètre du cercle au scale et je ne comprend pas a trouver ni résoudre mon erreur !
    Et vu que cet exercice n'est pas corrigé, je ne peut même pas me referer a la correction pour comprendre !

  2. #2
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir darioo2,

    Comme personne n'ose répondre je le fais: Désolé mais il y as trop d'erreurs.

    Reprend ton code à zéro:
    Regarde du coté de la portée des variables (self, entre autre)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        def __init__(self, boss=None):
            Frame.__init__(self)
            fen=Balle(larg=300, haut=300, ray=20)
            fen.pack(padx=10, pady=10, side=LEFT)
            mes = Regle()
            mes.pack()
            Button(text="Quitter", command=self.quit).pack(side=BOTTOM)
            # Désignation de l'evenement qui modifie le diamètre
            self.master.bind("<Control-Z>", self.modif)
     
        def modif(self, event):
            "Modification du diametre de la balle"
            self.fen.diametre(mes.taille.reglage)
    Et regarde bien la doc sur les Widgets tkinter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.ballon.itemconfig(?, self.larg/2-ray,self.haut/2-ray, self.larg/2+ray,self.haut/2+ray)
    Etc...

    Bon code

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 98
    Points : 57
    Points
    57
    Par défaut
    Merci pour ta réponse !
    Je vais tout reprendre depuis le début !
    @ +++

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Je n'ai pas trouver ton exercice dans le tuto mais relit bien la partie sur Scale.

    Pour reprendre ton code, et en restant dans l'esprit du chapitre 13, tu dois arriver à quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    # Exercice 13.20
    from tkinter import *
     
    # Création du canva
    class Balle(Canvas):
        "Représente une balle dans un canvas"
        def __init__(self, boss=None, larg=200, haut=150, ray=30, coul="red"):
            Canvas.__init__(self)
            self.larg, self.haut, self.balle = larg, haut, ray
            self.configure(width=self.larg, height=self.haut, bg="dark grey")
            self.ballon = self.create_oval(self.larg/2-ray,self.haut/2-ray,
                               self.larg/2+ray,self.haut/2+ray, width=2, fill=coul)
     
        def diametre(self, ray):
            "Modifie le rayon de la balle"
            self.coords(self.ballon, (self.larg/2-ray,self.haut/2-ray,
                               self.larg/2+ray,self.haut/2+ray))
     
    class Regle(Frame):
        "Scale permatant d'effectuer un reglage sur un objet"
        def __init__(self, boss=None):
            Frame.__init__(self)
            self.reglage = 0
            Scale(self, length=200, orient=VERTICAL, sliderlength=25,
                  label="Taille", from_=20, to=100, tickinterval=2,
                  resolution=5, showvalue=1, command=self.taille).pack()
     
        def taille(self, regl):
            self.reglage = int(regl)
            self.event_generate("<Control-Z>")
     
    if __name__ == '__main__':
     
       def modif(event):
           fen.diametre(mes.reglage)
     
       root = Tk()
       fen=Balle(larg=300, haut=300, ray=20)
       fen.pack(padx=10, pady=10, side=LEFT)
       mes=Regle()
       mes.pack()
       Button(text="Quitter", command=quit).pack(side=BOTTOM)
       # Désignation de l'evenement qui modifie le diamètre
       root.bind('<Control-Z>', modif)
       root.mainloop()
    Bon code

    ps: Mais essai quand même de le refaire toi même à partir des exemples du tuto.

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Re,

    root.quit bien sur

    @+

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 98
    Points : 57
    Points
    57
    Par défaut
    Merci pour ta réponse !

    Voici l'intitulé de l'exercice:

    13.20 Écrivez une petite application qui fait apparaître une fenêtre avec un canevas et un
    widget curseur (Scale). Dans le canevas, dessinez un cercle, dont l’utilisateur pourra
    faire varier la taille à l’aide du curseur.
    A force d'essayer et de rajouter des bouts de codes j'ai fait beaucoups trop d'erreurs

    Je vais comparer ton code au mien et bien comprendre mes erreurs pour ensuite essayer de refaire un programme dans le même thème. Je veut vraiment comprendre avant de passer a la suite !
    Merci encore pour ton aide !

  7. #7
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Dans ce cas la 'version simple'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    # Exercice 13.20
    from tkinter import *
     
    def taille(regl):
        root.ray = int(regl)
        root.event_generate("<Control-Z>")
     
    def modif(event=None):
        fen.coords(ballon, (larg/2-root.ray, haut/2-root.ray, larg/2+root.ray, haut/2+root.ray))
     
    root = Tk()
     
    larg, haut, root.ray = 300, 300, 30
     
    fen=Canvas(root, width=larg, height=haut)
    fen.pack(side=LEFT)
    ballon = fen.create_oval(larg/2-root.ray, haut/2-root.ray, larg/2+root.ray, haut/2+root.ray, width=2, fill="red")
     
    Scale(root, length=200, orient=VERTICAL, sliderlength=25,
        label="Taille", from_=20, to=100, tickinterval=2,
        resolution=5, showvalue=1, command=taille).pack(side=LEFT)
     
    Button(root, text="Quitter", command=root.quit).pack(side=BOTTOM)
     
    root.bind('<Control-Z>', modif)
    root.mainloop()
    Cela sera plus facile à comprendre.

    Bon code

  8. #8
    Membre à l'essai
    Profil pro
    Client Solution Developer
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Client Solution Developer

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    ayant fait aussi cet exercice, j'ai écrit un code tout à fait différent, qui ne fais pas appel à la classe Frame et donc n'utilise pas aussi la méthode event_generate().

    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    from Tkinter import *
     
    def cercle(can, x, y, r, coul):
        "Trace un cercle dont on connaît les coordonnées du centre et le rayon"
        return can.create_oval(x-r, y-r, x+r, y+r, outline=coul)
     
    class Application(Canvas):
        """Cercle dont le rayon varie grâce à un curseur"""
        def __init__(self, haut=200, larg=200, coul='purple'):
            Canvas.__init__(self)       #Constructeurs de la classe parente
            self.haut, self.larg = haut, larg
            self.liste=[0]  #Liste dans laquelle se trouvera la référence du cercle
     
            self.canevas = Canvas(self, width =larg, height =haut, bg ="grey80")
            self.canevas.pack(padx =10, pady =10)
     
            Scale(self, length=200, orient=HORIZONTAL, sliderlength =25,
                  label ='Rayon (en pixels) :', from_=0, to=100,
                  tickinterval =20, resolution =2, showvalue =1,
                  command = self.tracer).pack()
     
        def tracer(self, r):
            self.canevas.delete(self.liste[0])  #Efface le cercle précédent    
            self.liste[0] = cercle(self.canevas, self.larg/2, self.haut/2,\
                              int(r), 'blue')   #Trace le nouveau cercle
     
    if __name__ == '__main__':
        racine = Tk()
        c = Application(haut=250, larg=300)
        c.pack()
        racine.mainloop()
    Comme je suis débutant, je voudrais savoir si l'écriture de ce script est plus "efficace" qu'en passant par la classe Frame.

    Si c'est le cas, dans quel(s) cas est-il intéressant d'utiliser Frame?

    Merci de vos réponses!

  9. #9
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Frame est a prendre pour ce qu'il est : Un conteneur.
    Dans le cadre de l'énoncé en lui même c'est inutile. Le code final de darioo2 aurais pus être:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from Tkinter import *
     
    def modif(regl):
        fen.coords(ballon, (larg/2-int(regl), haut/2-int(regl),
            larg/2+int(regl), haut/2+int(regl)))
     
    root = Tk()
    larg, haut = 300, 300
    fen=Canvas(root, width=larg, height=haut)
    fen.pack(side=LEFT)
    ballon = fen.create_oval(larg/2-30, haut/2-30, 
        larg/2+30, haut/2+30, width=2, fill="red")
    Scale(root, length=200, orient=VERTICAL, sliderlength=25, 
        label="Taille", from_=20, to=100, tickinterval=2, resolution=5,
        showvalue=1, command=modif).pack(side=LEFT)
    Button(root, text="Quitter", command=root.quit).pack(side=BOTTOM)
    root.mainloop()
    L'event_generate() est un résidu inutile.

    Vous utilisez vous même un conteneur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Application(Canvas):
        def __init__(self, master, haut, larg, coul):
            Canvas.__init__
    Ce Canvas est inutile sauf qu'il fait office de conteneur pour le deuxième et Scale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    from Tkinter import *
     
    class Application(Canvas):
        def __init__(self, master, haut, larg, coul):
            Canvas.__init__(self, master, width=larg, height=haut, bg=coul)
            self.larg, self.haut = larg, haut
            self.obj = self.create_oval(self.larg/2-10, self.haut/2-10, self.larg/2+10, self.haut/2+10, outline='blue')
            Scale(self, length=200, orient=HORIZONTAL, sliderlength=25,
                  label='Rayon (en pixels) :', from_=0, to=100,
                  tickinterval=20, resolution=2, showvalue=1,
                  command=self.tracer).pack()
     
        def tracer(self, r):
            pass
     
    if __name__ == '__main__':
        racine = Tk()
        Application(racine, 250, 300, 'grey80').pack()
        racine.mainloop()
    A utiliser un conteneur autant utiliser le root
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from Tkinter import *
     
    class Application(Tk):
        def __init__(self, haut, larg):
            Tk.__init__(self)
            self.haut, self.larg = haut, larg
            self.canevas=Canvas(self, width=larg, height=haut, bg="grey80")
            self.canevas.pack(padx=10, pady=10)
            self.obj = self.canevas.create_oval(self.larg/2-10,
               self.haut/2-10, self.larg/2+10, self.haut/2+10,
               outline='blue')
            Scale(self, length=200, orient=HORIZONTAL, sliderlength=25,
               label='Rayon (en pixels) :', from_=0, to=100,
               tickinterval=20, resolution=2, showvalue=1,
               command = self.tracer).pack()
     
        def tracer(self, r):
            self.canevas.coords(self.obj, (self.larg/2-int(r),
               self.haut/2-int(r), self.larg/2+int(r), self.haut/2+int(r)))
     
    if __name__ == '__main__':
        c = Application(haut=250, larg=300)
        c.mainloop()
    Vous remarquerez l'utilisation de .coords(), le remplacement de la liste (une liste avec un seul élément ? pourquoi faire ?) par self.obj (self pour une utilisation dans tracer()) etc...

    Maintenant pour savoir qui est le plus efficace les deux répondent à l'énoncé. Le votre est plus proche (après correction) de ce qu'il est demandé par la suite.

    Bonne découverte.

  10. #10
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut Bonus
    Bonsoir,

    Comme votre code vas dans le bon sens au niveau des exercices voici de quoi réfléchir sur le sujet, avec des options (sans doute pour plus tard).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    try:
        import tkinter as Tk
    except:
        import Tkinter as Tk
     
    class Application(Tk.Tk):
        def __init__(self, haut, larg):
            Tk.Tk.__init__(self)
            canevas=Tk.Canvas(self, width=larg, height=haut, bg='#A9A9A9')
            canevas.pack(padx=10, pady=10)
            obj = canevas.create_oval(larg/2-10, haut/2-10, larg/2+10,
                haut/2+10, outline='#0000FF')
            Tk.Scale(self, length=200, orient=Tk.HORIZONTAL,
               sliderlength=25, label='Rayon (en pixels) :', from_=0,
               to=100, tickinterval=20, resolution=2, showvalue=1,
               command = lambda r: canevas.coords(obj, (larg/2-int(r),
               haut/2-int(r), larg/2+int(r), haut/2+int(r)))).pack()
     
    if __name__ == '__main__':
        app = Application(250, 300)
        app.mainloop()
        # Application(250, 300).mainloop()
    Bon code

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/04/2013, 17h58
  2. Réponses: 2
    Dernier message: 26/04/2012, 16h01
  3. Diamètre d'un cercle
    Par Décembre dans le forum MATLAB
    Réponses: 4
    Dernier message: 23/05/2011, 14h15
  4. Augmenter la diamètre d un cercle
    Par nypahe dans le forum Débuter
    Réponses: 3
    Dernier message: 06/07/2009, 19h07
  5. modification d'une cellule grace a du vba
    Par INCO13 dans le forum Macros et VBA Excel
    Réponses: 31
    Dernier message: 27/06/2008, 08h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo