Nsi horloge

Résolu

Bonjour,

Je dois réaliser une horloge en python mais un problème est vite arrivé.

Le problème provient de la méthode __str__. J'aimerais de l'aide pour le résoudre. Je ne dois pas utiliser le module time pour la réaliser.

from tkinter import *

class Horloge():
    def __init__(self, h, m, s):
        self.heure = h
        self.minute = m
        self.seconde = s

    def tictac(self):
        self.seconde += 1
        if self.seconde == 60:
            self.seconde = 0
            self.minute += 1
            if self.minute == 60:
                self.minute = 0
                self.heure += 1
                if self.heure == 24:
                    self.heure = 0

    def __str__(self):
        return f'{self.heure}:{self.minute}:{self.seconde}'


horloge = Horloge(12, 59, 50)
fenetre = Tk()
fenetre.title('Horloge')
fenetre.geometry('1920x1080+0+0')
fenetre.config(bg="white")
logo = PhotoImage(file="horloge.png")

mainloop()

Merci

Modération: pour une lecture plus facile du code, à l'avenir utilisez les balises voir cette page.

7 réponses

  1. Modérateur

    Bonjour,

    Pour afficher du code il faut utiliser l'icone ad-hoc en précisant le langage Python. Comme l'a corrigé un modérateur sur ta question.

    J'ai testé le code, pas d'affichage d'erreur, il faudrait montrer la tienne.

    Mais on peut se demander ce que tu fais. Je ne sais pas utiliser les classes, mais la tienne ne semble rien faire, si en ligne 25 tu fais un print(horloge) ta classe a renvoyé les paramètres que tu as passé. La fonction tictac() ne semble pas être actionnée.

    Et accessoirement tu n'affiches pas ton image dans la fenêtre Tk.


    1. Modérateur

      En rajoutant un appel à tictac() (si c'est bien la bonne façon de programmer ?) on obtient bien +1 s. Mais cela ne fait pas une boucle.

      from tkinter import *
      
      class Horloge():
          def __init__(self, h, m, s):
              self.heure=h
              self.minute=m
              self.seconde=s
          def tictac(self):
              self.seconde+=1
              if self.seconde==60:
                  self.seconde=0
                  self.minute+=1
                  if self.minute==60:
                      self.minute=0
                      self.heure+=1
                      if self.heure==24:
                          self.heure=0
          def __str__(self):
              self.tictac()
              return f'{self.heure}:{self.minute}:{self.seconde}'
      
      horloge = Horloge(12, 59, 50)
      print(horloge)
      
      fenetre = Tk()
      
      fenetre.title('Horloge')
      fenetre.geometry('600x600+0+0')
      fenetre.config(bg="white")
      
      logo = PhotoImage(file="horloge.png")
      
      mainloop()
  2. Bonjour,

    Le print(horloge) appelle la méthode __str__ qui incrémente le temps, et qui l'affiche une fois

    Mais si tu veux que le temps continue à s'écouler, tu comprends bien qu'il faut faire ça plusieurs fois de suite

    donc avec une boucle ...

    De plus, c'est fenetre.mainloop(), normalement

    1. Modérateur

      Bonjour

      Il faudrait utiliser la méthode after pour déclencher toutes les secondes un appel à la méthode tictac (voir cette discussion).

      Ensuite, tant que tu n'appelles pas (soit au travers d'un print, soit en mettant à jour ton interface graphique) :

      str(horloge)

      ... ta méthode Horloge.__str__  ne risque pas d'être traversée.

      Voici à quoi ça pourrait ressembler :

      from tkinter import *
      
      class Horloge(Tk):
          def __init__(self, h, m, s):
              super().__init__()
              self.heure = h
              self.minute = m
              self.seconde = s
              self.title("Horloge")
              self.geometry('400x400+0+0')
              self.label = Label(self, text="coucou")
              self.label.pack()
      
          def tictac(self):
              self.seconde += 1
              if self.seconde == 60:
                  self.seconde = 0
                  self.minute += 1
                  if self.minute == 60:
                      self.minute = 0
                      self.heure += 1
                      if self.heure == 24:
                          self.heure = 0
              self.label["text"] = f'{self.heure}:{self.minute}:{self.seconde}'
              self.after(1000, self.tictac)
      
      horloge = Horloge(12, 59, 50) 
      horloge.after(0, horloge.tictac)
      mainloop()

      Bonne chance

      1. Merci beaucoup à tous pour vos réponses qui m'ont permit de me débloquer.

        J'aimerais encore solliciter votre aider pour pouvoir avancer. Suite à ça j'ai voulu ajouter des boutons qui me permettent d'augmenter individuellement soit les heures, les minutes ou les secondes, ainsi qu'un autre permettant de stopper. Mais cela ne fonctionne pas (la zone graphique est en préparation pour pouvoir ajouter une image).Jj'apprécierais qu'on me débloque pour mon programme.

        from tkinter import *
        
        
        class Horloge(Tk):
            def __init__(self, h, m, s):
                super().__init__()
                self.heure = h
                self.minute = m
                self.seconde = s
                self.title("Horloge")
                self.geometry('1920x1080+0+0')
                self.label = Label(self, text="coucou", font=("times new roman", 50, "bold"), bg='white')
                self.label.pack()
        
            def tictac(self):
                self.seconde += 1
                if self.seconde == 60:
                    self.seconde = 0
                    self.minute += 1
                    if self.minute == 60:
                        self.minute = 0
                        self.heure += 1
                        if self.heure == 24:
                            self.heure = 0
                self.label["text"] = f'{self.heure}:{self.minute}:{self.seconde}'
                self.after(1000, self.tictac)
        
        horloge = Horloge(0, 0, 0)
        horloge.after(0, horloge.tictac)
        
        def augmenterH():
            global horloge
            self.heure += 1
            lbl_horloge.configure(text=augmenter)
        
        btn_augmenterH = Button(horloge, text = 'Augmenter', command=augmenterH, font=('times news roman', 10, 'bold'))
        btn_augmenterH.pack()
        btn_augmenterH.place(x=830, y=650, width=100, height=20)
        
        def augmenterM():
            global horloge
            self.minute += 1
            lbl_compteur.configure(text=augmenter)
        
        btn_augmenterM = Button(horloge, text = 'Augmenter', command=augmenterM, font=('times news roman', 10, 'bold'))
        btn_augmenterM.pack()
        btn_augmenterM.place(x=930, y=650, width=100, height=20)
        
        def augmenterS():
            global horloge
            self.seconde += 1
            lbl_horloge.configure(text=augmenter)
        
        btn_augmenterS = Button(horloge, text = 'Augmenter', command=augmenterS, font=('times news roman', 10, 'bold'))
        btn_augmenterS.pack()
        btn_augmenterS.place(x=1030, y=650, width=100, height=20)
        
        def stop():
            fenetre.after_cancel(id)
        
        btn_stop = Button(horloge, text = 'Stop', command=stop, font=('times news roman', 10, 'bold'))
        btn_stop.pack()
        btn_stop.place(x=650, y=710, width=100, height=20)
        
        #zone_graphique = Canvas(Horloge,width='1000',height='700',bg="white")
        #logo = PhotoImage(file="horloge.png")
        #zone_graphique.create_image(100,150, image=logo, anchor=NW)
        #zone_graphique.pack()
        
        mainloop()
        1. Bonjour,

          Il faut que tu affiches ton code avec les balises pour plus de lisibilité !

          mode d'emploi:

          https://codes-sources.commentcamarche.net/faq/11288-poster-un-extrait-de-code

          Visuellement, ça doit ressembler à ce que tu vois dans ton 1er message 

          A part ça

          ce n'est pas zone_graphique = Canvas(Horloge, mais zone_graphique = Canvas(fenetre_principale,

          et c'est fenetre_principale.mainloop à la fin

          Ton code dans un ordre plus logique (fonctions en premier) et avec les corrections (widgets créés sur fenetre et non sur horloge) :

          from tkinter import *
          
          class Horloge(Tk):
              def __init__(self, h, m, s):
                  super().__init__()
                  self.heure = h
                  self.minute = m
                  self.seconde = s
                  self.title("Horloge")
                  self.geometry('1920x1080+0+0')
                  self.label = Label(self, text="coucou", font=("times new roman", 50, "bold"), bg='white')
                  self.label.pack()
          
              def tictac(self):
                  self.seconde += 1
                  if self.seconde == 60:
                      self.seconde = 0
                      self.minute += 1
                      if self.minute == 60:
                          self.minute = 0
                          self.heure += 1
                          if self.heure == 24:
                              self.heure = 0
                  self.label["text"] = f'{self.heure}:{self.minute}:{self.seconde}'
                  self.after(1000, self.tictac)
          
          def stop():
              fenetre.after_cancel(id)
          
          def augmenterH():
              global horloge
              self.heure += 1
              lbl_horloge.configure(text=augmenter)
          
          def augmenterM():
              global horloge
              self.minute += 1
              lbl_compteur.configure(text=augmenter)
          
          def augmenterS():
              global horloge
              self.seconde += 1
              lbl_horloge.configure(text=augmenter)
          
          horloge = Horloge(0, 0, 0)
          horloge.after(0, horloge.tictac)
          
          fenetre = Tk()
          fenetre.title('Horloge')
          fenetre.geometry('1920x1080+0+0')
          fenetre.config(bg="white")
          
          zone_graphique = Canvas(fenetre,width='1000',height='700',bg="white")
          logo = PhotoImage(file="horloge.png")
          zone_graphique.create_image(100,150, image=logo, anchor=NW)
          zone_graphique.pack()
          
          btn_augmenterH = Button(fenetre, text = 'Augmenter', command=augmenterH, font=('times news roman', 10, 'bold'))
          #btn_augmenterH.pack() c'est pack ou c'est place mais pas les 2 !!!
          btn_augmenterH.place(x=830, y=650, width=100, height=20)
          
          btn_augmenterM = Button(fenetre, text = 'Augmenter', command=augmenterM, font=('times news roman', 10, 'bold'))
          #btn_augmenterM.pack()
          btn_augmenterM.place(x=930, y=650, width=100, height=20)
          
          btn_augmenterS = Button(fenetre, text = 'Augmenter', command=augmenterS, font=('times news roman', 10, 'bold'))
          #btn_augmenterS.pack()
          btn_augmenterS.place(x=1030, y=650, width=100, height=20)
          
          btn_stop = Button(fenetre, text = 'Stop', command=stop, font=('times news roman', 10, 'bold'))
          #btn_stop.pack()
          btn_stop.place(x=650, y=710, width=100, height=20)
          
          fenetre.mainloop()
          

          Bizarre quand même ta construction avec une fenêtre dans Horloge 

          il y a plus simple, non ?

          1. Modérateur

            Bonjour,

            N'utilise pas de variable globale, ça n'est pas utile et surtout les variables globales sont une très mauvaise habitude (elles nuisent à la lisibilité du code et pose des problèmes dès qu'on fait de la programmation concurrente). Chacune des fonctions permettant de corriger l'heure/les minutes/les secondes peut être simplement une lambda:

            class Horloge:
                # ...
                def set_seconds(self, s):
                    if not isisntace(s, int):
                        raise TypeError()
                    if not 0 <= s < 60:
                        raise ValueError()
                    self.secondes = s
            
            # ...
            btn_increment_seconds = Button(
              fenetre,
              command = lambda: horloge.set_seconds((horloge.secondes + 1) % 60)
            )

            Bonne chance

            1. Moi, je ferais ça:

              from tkinter import *
              
              class Horloge():
                  def __init__(self, h, m, s, L, F,stop):
                      self.heure = h
                      self.minute = m
                      self.seconde = s
                      self.L = L
                      self.F = F
                      self.stop = stop
              
                  def tictac(self):
                      self.seconde += 1
                      if self.seconde == 60:
                          self.seconde = 0
                          self.minute += 1
                          if self.minute == 60:
                              self.minute = 0
                              self.heure += 1
                              if self.heure == 24:
                                  self.heure = 0
              
                      self.L["text"] = f'{self.heure}:{self.minute}:{self.seconde}'
                      if(not self.stop): self.F.after(1000, self.tictac)
              
                  def set_seconds(self, s):
              
                      if not isinstance(s, int):
                          raise TypeError()
                      if not 0 <= s < 60:
                          raise ValueError()
                      self.seconde = s
              
              def stop(horloge):
                  horloge.stop = True
              
              fenetre = Tk()
              fenetre.title('Horloge')
              fenetre.geometry('600x300+0+0')
              fenetre.config(bg="white")
              
              zone_graphique = Canvas(fenetre,width=580,height=280,bg="white")
              zone_graphique.place(x=10,y=10)
              
              L1 = Label(zone_graphique,text = '',font = ('helvetica', 15, 'bold'))
              L1.place(x=20, y=20)
              
              btn_augmenterS = Button(fenetre, text = 'Augmenter S', command=lambda: horloge.set_seconds((horloge.seconde + 1) % 60), font=('times news roman', 10, 'bold'))
              btn_augmenterS.place(x=280, y=250)
              
              btn_stop = Button(fenetre, text = 'Stop', command=lambda: stop(horloge), font=('times news roman', 10, 'bold'))
              btn_stop.place(x=410, y=250)
              
              horloge = Horloge(0, 0, 0, L1,zone_graphique, False)
              horloge.tictac()
              
              fenetre.mainloop()