[python] à quoi sert le focus ???

Résolu
Bonjour,

J'aimerai savoir à quoi sert le focus dans python ainsi que cette commande focus_set()

merci, d'avance !!!
--
@--ToDeSfAlL--@
Configuration: Windows XP
Internet Explorer 6.0

54 réponses

Résumé de la discussion

Le focus en Python, notamment dans les interfaces Tkinter, désigne l'élément qui reçoit les évènements clavier, et focus_set() permet de désigner explicitement le widget actif pour les saisies. Plusieurs réponses expliquent qu'il sert à choisir quel widget reçoit le focus, afin que les saisies clavier soient dirigées vers ce composant et non vers les autres éléments de l'interface. Des remarques techniques illustrent des pièges, notamment avec grid qui peut retourner None si l'on écrit entr1 = Entry(fen1).grid(...); il faut créer l'Entry puis l'affecter à entr1 avant d'appeler grid et ensuite appeler entr1.focus_set(). Enfin, certains suggèrent d'envisager des bibliothèques graphiques plus avancées, comme wxPython, lorsque les interfaces deviennent complexes, car Tkinter présente des limites pour des projets plus élaborés.

Bobot (l’IA à votre service)
  1. Modérateur
    ça sert à choisir quel widget a le focus.

    lapin comprî ? :-D

    J'explique: par exemple dans une interface graphique, il peut y avoir plusieurs zones de texte.
    Quand tu tape, le texte s'inscrit dans la zone qui est actuellement active, celle qui a le focus.

    set_focus() permet de désigner une zone de texte, un bouton ou n'importe quoi d'autre qui recevra les évènements clavier.
  2. merci infiniment pour votre réponse . mais sis je le suprime de mon ordinateur est ce grave...?
    1. Bonjour,

      Est-ce que tu sais si python à une fonction imprimable, c'est t'a dire que les données que l'utilisateur rentre je voudrais qu'il me les imprime sur papier. C'est possible ????
      1. Modérateur
        Je ne sais pas désolé.

        Peut-être en regarde du côté de la méthode geometry()
        1. Bonjour, ce n'est pas un problème que j'ai cette fois-ci !!!!!!

          Lorsque je lance mon programme j'ai plusieurs fenetre qui s'ouvre les unes après les autres et elles ne sont jamais à la même place.

          Comment faire pour qu'elle s'ouvre toujours au même endroit ?

          1. Modérateur
            Juste avant le while, ajoute:
            print type(nb_code),type(i)

            Et là tu verra:
            <type 'str'> <type 'int'>


            Autrement dit tu es en train de comparer une chaine avec un nombre :-)

            Pour que ça marche correctement, il faudrait remplacer la ligne:
            self.nb_code = self.champNum1.get()

            par:
            self.nb_code = int(self.champNum1.get())
            1. excuse moi mais j'ai un petit problème je te met le code :

              # -*- coding: iso-8859-1 -*-
              
              
              ################################
              # Import des librairies utiles #
              ################################
              import sys, time, os, os.path, shutil
              from pprint import *
              #~ import time
              import locale
              from Tkinter import *
              import Tkinter
              import Pmw
              
              class liste_equipement_nb_code(Tkinter.Toplevel):
              	def __init__(self, parent):
              		Tkinter.Toplevel.__init__(self, parent)
              		self.title('Liste des équipements')
              		self.parent = parent
              		self.suite()
              
              	def suite(self):
              		self.champNum1 = Tkinter.StringVar()
              		text1 = Tkinter.Label(self, text = "Quel est le nombre de code maintenance ? ").grid(row = 0, sticky = W)
              		entr1 = Tkinter.Entry(self, textvariable = self.champNum1, width = 4)
              		entr1.grid(row = 0, column = 1)
              		entr1.focus_set()
              		ok = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_nb_code).grid(row = 1, column = 1)
              
              	def recup_nb_code(self):
              		self.nb_code = self.champNum1.get()
              		self.destroy()
              
              class liste_equipement_code(Tkinter.Toplevel):
              	def __init__(self, parent):
              		Tkinter.Toplevel.__init__(self, parent)
              		self.title('Liste des équipements')
              		self.parent = parent
              		self.suite()
              
              	def suite(self):
              		self.champText1 = Tkinter.StringVar()
              		self.champText2 = Tkinter.StringVar()
              		self.champText3 = Tkinter.StringVar()
              		text1 = Tkinter.Label(self, text = "Code maintenance : ").grid(row = 0, sticky = W)
              		text2 = Tkinter.Label(self, text = "Equipement à configurer : ").grid(row = 1, sticky = W)
              		text3 = Tkinter.Label(self, text = "Opérations à réaliser : ").grid(row = 2, sticky = W)
              		entr1 = Tkinter.Entry(self, textvariable = self.champText1, width = 7)
              		entr1.grid(row = 0, column = 1)
              		entr1.focus_set()
              		entr2 = Tkinter.Entry(self, textvariable = self.champText2, width = 45).grid(row = 1, column = 1)
              		entr3 = Tkinter.Entry(self, textvariable = self.champText3, width = 45).grid(row = 2, column = 1)
              		ok = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_code).grid(row = 3, column = 1)
              
              	def recup_code(self):
              		self.code = self.champText1.get()
              		self.equipement = self.champText2.get()
              		self.operation = self.champText3.get()
              		self.destroy()
              
              class Application(Tkinter.Tk):
              	"""Application principale"""
              	def __init__(self, parent = None):
              		Tkinter.Tk.__init__(self)
              		self.parent = parent
              		self.title('Dossier Machine')
              		self.configure(menu=self.createMenu())
              		self.can = Canvas(self,bg='light grey', height = 190, width=250, borderwidth = 2)
              		self.can.pack()
              
              	def createMenu(self):
              
              		menubar = Tkinter.Menu(self)
              		
              		### Menu <Fichier> ###
              		me1 = Menu(menubar)
              		me1.add_command(label = 'Nouveau dossier machine', underline = 0, command = self.nouveau_dossier)
              		me1.add_command(label = 'Nouveau dossier machine avec aide', underline = 1)
              		me1.add_separator()
              		me1.add_command(label = 'Imprimer', underline = 0)
              		me1.add_separator()
              		me1.add_command(label = 'Quitter', underline = 0, command = self.quit)
              		menubar.add_cascade(label="Fichier", menu=me1)
              
              		### Menu <Edition> ###
              		me2 = Menu(menubar)
              		me2.add_command(label = 'Copier', underline = 4)
              		me2.add_command(label = 'Coller', underline = 1)
              		menubar.add_cascade(label="Edition", menu=me2)
              
              		### Menu <Aide> ###
              		me3 = Menu(menubar)
              		me3.add_command(label = 'Aide', underline = 0)
              		me3.add_separator()
              		me3.add_command(label = 'A propos de...', underline = 7)
              		menubar.add_cascade(label="Aide", menu=me3)
              
              		return menubar
              
              	def nouveau_dossier(self):
              		equipement_nb_code = liste_equipement_nb_code(self)
              		self.wait_window(equipement_nb_code)
              		nb_code = equipement_nb_code.nb_code
              		print nb_code
              
              		i = 0
              		lst_code = []
              		lst_equipement = []
              		lst_operation = []
              		while i < nb_code:
              			equipement_code = liste_equipement_code(self)
              			self.wait_window(equipement_code)
              			i = i+1
              			print i     
              
              if __name__ == '__main__':
              	app = Application()
              	app.mainloop()
              


              Quand je fais fichier nouveau dossier machine, il me demande le nombre de code main et suivant le résultat je lui met il n'affiche pas le nombre correct de fenetre que je veu. Essaye le. Comment faire pour le fasse autant de fois que je veux ?
              1. ok merci c'est vraiment gentil à toi. Tout ce que tu as fait pour moi va beaucoup m'aider alors encore merci. Si j'ai encore des problème je renvoie un message.
                1. Modérateur
                  OK Merci c cool, mais comment détruire la fenetre après que j'ai recup mon entry.

                  Voir les lignes que j'ai ajoutée/modifiées en gras:

                  # -*- coding: iso-8859-1 -*-
                  
                  from Tkinter import *
                  import Tkinter
                  import Tkinter as Tk
                  
                  
                  class propos(Tkinter.Toplevel):
                      def __init__(self,parent):
                          Tkinter.Toplevel.__init__(self,parent)
                          #self.title('A propos de ...')
                          self.parent = parent
                          self.initialize()
                  
                      def initialize(self):
                          test = 0
                          champNum1 = Tkinter.IntVar()
                          text1 = Tkinter.Label(self, text = "Dossier Machine 2007").grid(row = 0, sticky = W)
                          text2 = Tkinter.Label(self, text = "Part of *** Edition 2007").grid(row = 1, sticky = W)
                          text3 = Tkinter.Label(self, text = "Copyright (c) ***. Tous droits réservés.").grid(row = 2, sticky = W)
                          text4 = Tkinter.Label(self, text = "Version 1.01").grid(row = 3, sticky = W)
                          text5 = Tkinter.Label(self, text = "Licence d'utilisation accordée à :").grid(row = 4, sticky = W)
                          text6 = Tkinter.Label(self, text = "    - ***").grid(row = 5, sticky = W)
                          button = Tkinter.Button(self, text = "OK", width = 15, textvariable = champNum1, command = self.destroy)
                          button.grid(row = 6, column = 0)
                          button.focus_set()
                  
                  class monessai(Tkinter.Toplevel):
                      def __init__(self,parent):
                          Tkinter.Toplevel.__init__(self,parent)
                          self.title('test_entry')
                          self.parent = parent
                          self.initialize()
                  
                      def initialize(self):
                          self.champText1 = Tkinter.StringVar()
                          text1 = Tkinter.Label(self, text = "reponse").grid(row = 0, sticky = W)
                          entr1 = Tkinter.Entry(self, textvariable = self.champText1).grid(row = 0, column = 1)
                          button = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_donnee)
                          button.grid(row = 6, column = 0)
                          button.focus_set()
                          
                      def recup_donnee(self):
                          self.valeur = self.champText1.get()
                          self.destroy()
                  
                  class Application(Tkinter.Tk):
                      """Application principale"""
                      def __init__(self, parent = None):
                          Tkinter.Tk.__init__(self)
                          self.parent = parent
                          self.title('Dossier Machine')
                          self.configure(menu=self.createMenu())
                          self.can = Canvas(self,bg='light grey', height = 190, width=250, borderwidth = 2)
                          self.can.pack()
                  
                      def createMenu(self):
                  
                          menubar = Tkinter.Menu(self)
                          
                          ### Menu <Fichier> ###
                          me1 = Menu(menubar)
                          me1.add_command(label = 'Nouveau dossier machine', underline = 0)
                          me1.add_command(label = 'Nouveau dossier machine avec aide', underline = 1)
                          me1.add_separator()
                          me1.add_command(label = 'Imprimer', underline = 0)
                          me1.add_separator()
                          me1.add_command(label = 'Quitter', underline = 0, command = self.quit)
                          menubar.add_cascade(label="Fichier", menu=me1)
                  
                          ### Menu <Edition> ###
                          me2 = Menu(menubar)
                          me2.add_command(label = 'Copier', underline = 4)
                          me2.add_command(label = 'Coller', underline = 1)
                          menubar.add_cascade(label="Edition", menu=me2)
                  
                          ### Menu <Aide> ###
                          me3 = Menu(menubar)
                          me3.add_command(label = 'Aide', underline = 0, command = self.essai)
                          me3.add_separator()
                          me3.add_command(label = 'A propos de...', underline = 7, command = self.propos)
                          menubar.add_cascade(label="Aide", menu=me3)
                  
                          return menubar        
                          
                      def propos(self):
                          propos(self)
                  
                      def essai(self):
                          m = monessai(self)
                          self.wait_window(m)  # On attend la fermeture de la fenêtre.
                          print "La valeur entree est ",m.valeur
                  
                  if __name__ == '__main__':
                      app = Application()
                      app.mainloop()
                  
                  1. Modérateur
                    Voilà c'est corrigé. Le menu n'était pas créé correctement:

                    # -*- coding: iso-8859-1 -*-
                    
                    from Tkinter import *
                    import Tkinter
                    import Tkinter as Tk
                    
                    
                    class propos(Tkinter.Toplevel):
                        def __init__(self,parent):
                            Tkinter.Toplevel.__init__(self,parent)
                            #self.title('A propos de ...')
                            self.parent = parent
                            self.initialize()
                    
                        def initialize(self):
                            test = 0
                            champNum1 = Tkinter.IntVar()
                            text1 = Tkinter.Label(self, text = "Dossier Machine 2007").grid(row = 0, sticky = W)
                            text2 = Tkinter.Label(self, text = "Part of *** Edition 2007").grid(row = 1, sticky = W)
                            text3 = Tkinter.Label(self, text = "Copyright (c) ***. Tous droits réservés.").grid(row = 2, sticky = W)
                            text4 = Tkinter.Label(self, text = "Version 1.01").grid(row = 3, sticky = W)
                            text5 = Tkinter.Label(self, text = "Licence d'utilisation accordée à :").grid(row = 4, sticky = W)
                            text6 = Tkinter.Label(self, text = "    - ***").grid(row = 5, sticky = W)
                            button = Tkinter.Button(self, text = "OK", width = 15, textvariable = champNum1, command = self.destroy)
                            button.grid(row = 6, column = 0)
                            button.focus_set()
                    
                    class monessai(Tkinter.Toplevel):
                        def __init__(self,parent):
                            Tkinter.Toplevel.__init__(self,parent)
                            self.title('test_entry')
                            self.parent = parent
                            self.initialize()
                    
                        def initialize(self):
                            self.champText1 = Tkinter.StringVar()
                            text1 = Tkinter.Label(self, text = "reponse").grid(row = 0, sticky = W)
                            entr1 = Tkinter.Entry(self, textvariable = self.champText1).grid(row = 0, column = 1)
                            button = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_donnee)
                            button.grid(row = 6, column = 0)
                            button.focus_set()
                            
                        def recup_donnee(self):
                            test = self.champText1.get()
                            print test  
                        
                    
                    class Application(Tkinter.Tk):
                        """Application principale"""
                        def __init__(self, parent = None):
                            Tkinter.Tk.__init__(self)
                            self.parent = parent
                            self.title('Dossier Machine')
                            self.configure(menu=self.createMenu())
                            self.can = Canvas(self,bg='light grey', height = 190, width=250, borderwidth = 2)
                            self.can.pack()
                    
                        def createMenu(self):
                    
                            menubar = Tkinter.Menu(self)
                            
                            ### Menu <Fichier> ###
                            me1 = Menu(menubar)
                            me1.add_command(label = 'Nouveau dossier machine', underline = 0)
                            me1.add_command(label = 'Nouveau dossier machine avec aide', underline = 1)
                            me1.add_separator()
                            me1.add_command(label = 'Imprimer', underline = 0)
                            me1.add_separator()
                            me1.add_command(label = 'Quitter', underline = 0, command = self.quit)
                            menubar.add_cascade(label="Fichier", menu=me1)
                    
                            ### Menu <Edition> ###
                            me2 = Menu(menubar)
                            me2.add_command(label = 'Copier', underline = 4)
                            me2.add_command(label = 'Coller', underline = 1)
                            menubar.add_cascade(label="Edition", menu=me2)
                    
                            ### Menu <Aide> ###
                            me3 = Menu(menubar)
                            me3.add_command(label = 'Aide', underline = 0, command = self.essai)
                            me3.add_separator()
                            me3.add_command(label = 'A propos de...', underline = 7, command = self.propos)
                            menubar.add_cascade(label="Aide", menu=me3)
                    
                            return menubar        
                            
                        def propos(self):
                            propos(self)
                    
                        def essai(self):
                            monessai(self)
                    
                    if __name__ == '__main__':
                        app = Application()
                        app.mainloop()
                    
                    1. OK Merci c cool, mais comment détruire la fenetre après que j'ai recup mon entry.
                      1. Modérateur
                        Minute !

                        J'ai fait une erreur dans mon source précédent.

                        Je corrige et je republie.
                        1. Modérateur
                          Encore une remarque:
                          Si tu commences à créer des interfaces graphiques plus complexes, il peut être intéressant de laisser tomber tkinter et prendre wxPython (=wxWidgets).

                          tkinter a ses limites, et wxWidgets permet d'aller beaucoup plus loin.
                          https://www.wxpython.org/

                          tkinter n'est vraiment adapté qu'aux interfaces graphiques simples
                          (j'ai poussé le bouchon un peu loin en utilisant tkinter pour webGobbler, et je ne referai pas cette erreur.)
                          1. Modérateur
                            Plusieurs remarques:

                            ---

                            arf... oui, excuses-moi, j'aurais dû tilter:
                            Tkinter.Tk est la fenêtre racine. Il ne doit y en avoir qu'une seule et ça doit être ta fenêtre principale.

                            Donc la classe essai (ou monessai) ne doit pas dériver de Tkinter.Tk mais d'autrechose, par exemple de Tkinter.Toplevel
                            (Toplevel est une fenêtre possédant des contrôles (agrandir, fermer, minimiser, etc.))
                            (voir source plus loin)

                            ---
                            Quand tu créé tes objets propos() et monessai(), il est important de passer self en paramètre.
                            Sinon les fenêtres apropos et autres ne seront pas détruites quand ta fenêtre principale est fermée.
                            (voir source plus loin)

                            ---

                            Note que si tu dois dériver d'une classe existante, évite d'utiliser des paramètres d'initialisation différent: N'utilise pas 'boss', mais parent.
                            (voir source plus loin)

                            ---

                            Enfin, puisque ton menu est un widget contenu dans ta fenêtre principale, il n'y a pas vraiement d'intérêt à en faire une classe séparée.

                            Ce qui donne:
                            # -*- coding: iso-8859-1 -*-
                            
                            from Tkinter import *
                            import Tkinter
                            import Tkinter as Tk
                            
                            
                            class propos(Tkinter.Toplevel):
                                def __init__(self,parent):
                                    Tkinter.Toplevel.__init__(self,parent)
                                    #self.title('A propos de ...')
                                    self.parent = parent
                                    self.initialize()
                            
                                def initialize(self):
                                    test = 0
                                    champNum1 = Tkinter.IntVar()
                                    text1 = Tkinter.Label(self, text = "Dossier Machine 2007").grid(row = 0, sticky = W)
                                    text2 = Tkinter.Label(self, text = "Part of *** Edition 2007").grid(row = 1, sticky = W)
                                    text3 = Tkinter.Label(self, text = "Copyright (c) ***. Tous droits réservés.").grid(row = 2, sticky = W)
                                    text4 = Tkinter.Label(self, text = "Version 1.01").grid(row = 3, sticky = W)
                                    text5 = Tkinter.Label(self, text = "Licence d'utilisation accordée à :").grid(row = 4, sticky = W)
                                    text6 = Tkinter.Label(self, text = "    - ***").grid(row = 5, sticky = W)
                                    button = Tkinter.Button(self, text = "OK", width = 15, textvariable = champNum1, command = self.destroy)
                                    button.grid(row = 6, column = 0)
                                    button.focus_set()
                            
                            class monessai(Tkinter.Toplevel):
                                def __init__(self,parent):
                                    Tkinter.Toplevel.__init__(self,parent)
                                    self.title('test_entry')
                                    self.parent = parent
                                    self.initialize()
                            
                                def initialize(self):
                                    self.champText1 = Tkinter.StringVar()
                                    text1 = Tkinter.Label(self, text = "reponse").grid(row = 0, sticky = W)
                                    entr1 = Tkinter.Entry(self, textvariable = self.champText1).grid(row = 0, column = 1)
                                    button = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_donnee)
                                    button.grid(row = 6, column = 0)
                                    button.focus_set()
                                    
                                def recup_donnee(self):
                                    test = self.champText1.get()
                                    print test  
                                
                            
                            class Application(Tkinter.Tk):
                                """Application principale"""
                                def __init__(self, parent = None):
                                    Tkinter.Tk.__init__(self)
                                    self.parent = parent
                                    self.title('Dossier Machine')
                                    self.configure(menu=self.createMenu())
                                    #self.can = Canvas(self,bg='light grey', height = 190, width=250, borderwidth = 2)
                                    #self.can.pack()
                            
                                def createMenu(self):
                            
                                    mymenu = Tkinter.Menu(self)
                                    ### Menu <Fichier> ###
                                    fileMenu = Menubutton(self, text = 'Fichier')
                                    fileMenu.grid(column=0,row=0)
                                    # Partie déroulante :
                                    me1 = Menu(fileMenu)
                                    me1.add_command(label = 'Nouveau dossier machine', underline = 0)
                                    me1.add_command(label = 'Nouveau dossier machine avec aide', underline = 1)
                                    me1.add_separator()
                                    me1.add_command(label = 'Imprimer', underline = 0)
                                    me1.add_separator()
                                    me1.add_command(label = 'Quitter', underline = 0, command = self.quit)
                                    # Intégration du menu :
                                    fileMenu.configure(menu = me1)
                            
                                    ### Menu <Edition> ###
                                    fileMenu = Menubutton(self, text = 'Edition')
                                    fileMenu.grid(column=1,row=0)
                                    # Partie déroulante
                                    me2 = Menu(fileMenu)
                                    me2.add_command(label = 'Copier', underline = 4)
                                    me2.add_command(label = 'Coller', underline = 1)
                                    # Intégration du menu :
                                    fileMenu.configure(menu = me2)
                            
                                    ### Menu <Aide> ###
                                    fileMenu = Menubutton(self, text = 'Aide')
                                    fileMenu.grid(column=2,row=0)
                                    # Partie déroulante
                                    me3 = Menu(fileMenu)
                                    me3.add_command(label = 'Aide', underline = 0, command = self.essai)
                                    me3.add_separator()
                                    me3.add_command(label = 'A propos de...', underline = 7, command = self.propos)
                                    # Intégration du menu :
                                    fileMenu.configure(menu = me3)
                            
                                    return mymenu        
                                    
                                def propos(self):
                                    propos(self)
                            
                                def essai(self):
                                    monessai(self)
                            
                            if __name__ == '__main__':
                                app = Application()
                                app.mainloop()


                            Et là on récupère bien les valeurs de l'entry.

                            (J'ai désactivé ton canvas pour des raisons d'alignement dont il faudra s'occuper après...)
                            1. Je suis d'accord avec toi, pour le code ci-dessus, chez moi aussi il fonctionne mais mais la classe dans le bout de programme au commentaire 30, et tu verras ke ça ne marche pas.
                              1. Modérateur
                                Chez moi, le programme suivant fonctionne très bien et je récupère la valeur quand je clic sur le bouton "OK":

                                # -*- coding: iso-8859-1 -*-
                                
                                from Tkinter import *
                                import Tkinter
                                import Tkinter as Tk
                                
                                class essai(Tkinter.Tk):
                                	def __init__(self,parent):
                                		Tkinter.Tk.__init__(self,parent)
                                		self.title('test_entry')
                                		self.parent = parent
                                		self.initialize()
                                
                                	def initialize(self):
                                		self.champText1 = Tkinter.StringVar()
                                		self.text1 = Tkinter.Label(self, text = "reponse").grid(row = 0, sticky = W)
                                		self.entr1 = Tkinter.Entry(self, textvariable = self.champText1)
                                		self.entr1.grid(row = 0, column = 1)
                                		self.button = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_donnee)
                                		self.button.grid(row = 6, column = 0)
                                		self.button.focus_set()
                                		
                                	def recup_donnee(self):
                                		print self.champText1.get()
                                if __name__ == '__main__':
                                	app = essai(None)
                                	app.mainloop()


                                Copie d'écran: https://imageshack.com/
                                1. class essai(Tkinter.Tk):
                                  	def __init__(self,parent):
                                  		Tkinter.Tk.__init__(self,parent)
                                  		self.title('test_entry')
                                  		self.parent = parent
                                  		self.initialize()
                                  
                                  	def initialize(self):
                                  		self.champText1 = Tkinter.StringVar()
                                  		self.text1 = Tkinter.Label(self, text = "reponse").grid(row = 0, sticky = W)
                                  		self.entr1 = Tkinter.Entry(self, textvariable = self.champText1)
                                  		self.entr1.grid(row = 0, column = 1)
                                  		self.button = Tkinter.Button(self, text = "OK", width = 15, command = self.recup_donnee)
                                  		self.button.grid(row = 6, column = 0)
                                  		self.button.focus_set()
                                  		
                                  	def recup_donnee(self):
                                  		print self.champText1.get()


                                  Comme ça c'est bon. Si ça l'est et bien je n'arrive toujours pas à récupérer l'entry.
                                  • 1
                                  • 2
                                  • 3