Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème gestion raccourci

python 3.x

Sujet résolu
    16 novembre 2011 à 1:00:26

    Bonjour!

    Alors mon problème est ... chiant à résoudre je me gratte la tête mais je vois pas par ou commencer.

    vais d'abord vous montrer mon code puis expliquer le but de ce que je veux faire

    # -*- coding: cp1250 -*-
    from Tkinter import *
    import tkFileDialog
    import os
    
    root = Tk()
    root.title('Shortcuto: Gérer vos raccourcis facilement')
    root.iconbitmap("ico_shortcuto.ico")
    
    
    def Rajouter():
        global filename
        filename = tkFileDialog.askopenfilename(parent=root, title = 'Choisissez un raccourcis a cree')
        btnRajouter = Button(root, text = 'test', command = Crea_raccourci)
        btnRajouter.pack()
    def Crea_raccourci():
        os.startfile(filename)
    
      
    btnParcourir = Button(root, text ='Parcourir', command = Parcourir)
    btnParcourir.pack()
    root.mainloop()
    


    Au fait la le bouton parcourir sert à ajouter un bouton dans la fenêtre principale permettant d'ouvrir un fichier choisi par l'utilisateur, un raccourcis vers ce fichier quoi.

    ça marche bien niveau rajout de bouton dans la fenêtre principale root (je parle pas de l’esthétique). ça me fait à chaque fois un nouveau bouton avec un raccourci c'est génial.

    le problème c'est que quand je veux choisir un autre raccourci alors c'est tout les raccourcis de tout les boutons qui sont mis à jour et qui mène vers ce nouveau raccourci, vu que filename à changer de chemin.

    et moi j'aimerai retenir l'ancien choix, mais je sais pas comment faire. Pour moi logiquement je devrait utiliser à chaque fois une nouvelle variable pour chaque raccourcis , mais HOW? je pense pas que c'est possible.

    alors je vous demande de l'aide à trouver un autre moyen svp :(

    En gros chaque bouton aura un raccourcis différent à la fin . le nom du bouton je sais comment faire ça sert à rien que je le mette ici c'est pas la question(vu que la ils sont tous nommé 'Test' dans cette démo).

    Le but c'est de faire:

    Boutton 1: ouvre image.jpg
    Boutton 2: ouvre film.wmv

    etc

    Merci de votre aide

    PS: c'est un projet personnel je le fait pour moi
    • Partager sur Facebook
    • Partager sur Twitter
      16 novembre 2011 à 1:32:47

      Salut,

      Un simple indice : ta ligne 12.

      global filename
      


      On a un léger problème là ; si filename est une variable globale, vue la façon dont ton code est fichu, tous tes boutons auront pour effet d'ouvrir le fichier dont le chemin se trouve dans cette variable, soit le dernier fichier dont le chemin lui a été assigné. Le comportement du programme est parfaitement logique.

      Une solution serait par exemple de virer ta ligne 12, puis de faire une fonction comme ceci :

      def crea_raccourcis(filename):
          def commande():
              os.startfile(filename)
          return commande
      


      C'est un peu tricky quand on n'a pas l'habitude (ça s'appelle une closure), mais la seule solution alternative, ce serait de faire une classe dont tu surcharges la méthode __call__ (i.e. un foncteur, en POO), ce qui est moins élégant, et un poil plus complexe pour pas grand-chose.

      Du coup, ta ligne 14 deviendrait :

      btnRajouter = Button(root, text = 'test', command = crea_raccourcis(filename))
      


      PS : Je n'ai pas testé le code (je fuis TkInter comme la peste noire), mais je suis quelqu'un de confiant. :)
      • Partager sur Facebook
      • Partager sur Twitter
      Zeste de Savoir, le site qui en a dans le citron !
      Anonyme
        16 novembre 2011 à 6:20:19

        @Nohar ça ne peut pas fonctionner, en effet tkinter ne fonctionnera pas dans la logique des choses (fonction avec argument), il faudra utiliser lambda

        btnRajouter = Button(root, text = 'test', command = lambda : crea_raccourcis(filename))
        
        • Partager sur Facebook
        • Partager sur Twitter
          16 novembre 2011 à 7:38:29

          Heuu, j'aurais tendance à dire "teste le code" pour le coup parce que je ne vois absolument pas ce qui pourrait poser problème ici, etque je vois mal comment ton code pourrait marcher : tu lui passes une fonction sans argument qui retourne une fonction sans argument...
          • Partager sur Facebook
          • Partager sur Twitter
          Zeste de Savoir, le site qui en a dans le citron !
          Anonyme
            16 novembre 2011 à 8:22:31

            tkinter hélas...

            bizarre mais je ne pense pas me tromper. en tout cas ta proposition est incorrecte c'est certains.

            je peux pas tester, mais c'est du 99,9%
            • Partager sur Facebook
            • Partager sur Twitter
              16 novembre 2011 à 8:56:09

              Sachant que mon crea_raccourcis(filename) retourne une fonction qui ne prend pas d'argument, je vois mal ce qui pourrait poser problème... tu serais pas embrouillé par le fait sur ma fonction retourne une autre fonction, par hasard ?

              Edit : Pour couper la poire en deux, on peut faire la même chose que ma fonction mais avec une lambda :

              btnRajouter = Button(root, text = 'test', command = lambda: os.startfile(filename))
              


              Mais ça revient strictement au même que le résultat de l'évaluation de crea_raccourcis(filename), sauf que la méthode que je propose a le mérite de pouvoir être adaptée relativement facilement à des traitements plus complexes. La lambda, ici, est strictement équivalente à ma fonction command().

              • Partager sur Facebook
              • Partager sur Twitter
              Zeste de Savoir, le site qui en a dans le citron !
                16 novembre 2011 à 11:07:19

                C'est parfait ça la commande lambda à fonctionner. ça garde en mémoire l'ancien raccourcis ;D Génial

                La première solution sans la commande lambda m'ouvrait directement le raccourci et le bouton qui as était crée n'appeler pas le raccourci.

                voici le code après changement:

                # -*- coding: cp1250 -*-
                from Tkinter import *
                import tkFileDialog
                import os
                
                root = Tk()
                root.title('Shortcuto: Gérer vos raccourcis facilement')
                root.iconbitmap("ico_shortcuto.ico")
                
                
                def Rajouter():
                    def Crea_raccourcis(filename):
                        os.startfile(filename)
                    filename = tkFileDialog.askopenfilename(parent=root, title = 'Choisissez un raccourcis a cree')
                    btnRajouter = Button(root, text = 'test', command =lambda : Crea_raccourcis(filename))
                    btnRajouter.pack()
                  
                btnParcourir = Button(root, text ='Parcourir', command = Rajouter)
                btnParcourir.pack()
                root.mainloop()
                


                Merci beaucoup!!

                Vous pouvez m'expliquer brièvement ce que lambda fait svp ? ^^
                • Partager sur Facebook
                • Partager sur Twitter
                  16 novembre 2011 à 11:37:26

                  Il s'agit simplement de sucre syntaxique pour créer une fonction toute simple dont la valeur de retour tient en une seule instruction.

                  Un exemple valant mieux qu'un long discours :

                  Python 3.2.2 (default, Sep  5 2011, 04:33:58) 
                  [GCC 4.6.1 20110819 (prerelease)] on linux2
                  Type "help", "copyright", "credits" or "license" for more information.
                  >>> lambda : 4
                  <function <lambda> at 0xb701c1ac>
                  >>> fonction = lambda : 4
                  >>> fonction()
                  4
                  >>> fonction = lambda a: a * 2
                  >>> fonction(21)
                  42
                  >>> fonction = lambda a, b: a + b
                  >>> fonction(3, 2)
                  5
                  


                  Citation


                  La première solution sans la commande lambda m'ouvrait directement le raccourci et le bouton qui as était crée n'appeler pas le raccourci.



                  Si tu as utilisé pour ça la fonction crea_raccourcis qui est dans ton code actuel (et qui n'est pas celle que je t'ai montrée), c'est normal. Sinon c'est que tu as mal recopié ma fonction. Il est juste impossible que la fonction que je t'ai montrée se comporte comme ça à moins que tu n'écrives crea_raccourcis(filename)() avec des parenthèses vides à la fin.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Zeste de Savoir, le site qui en a dans le citron !
                    16 novembre 2011 à 12:40:42

                    ouah vraiment pas mal ce lambda :o il pourra bien me servir plus d'une fois je pense :o

                    Sinon oui c’était ma faute ^^ dans le programme d'origine les deux méthodes marche ^^

                    cependant, j'ai gardé lambda j'aime bien le nom haha

                    Si je fini mon projet je le posterai sur le forum ça peut servir je pense ^^

                    faut encore que je me creuse la tête pour export/import mais je pense le gérer avec un fichier texte (histoire de se souvenir des raccourcis)

                    Merci en tout cas, ça fait plaisir des réponses rapide et en plus qui résolvent le problème ;D
                    • Partager sur Facebook
                    • Partager sur Twitter
                      16 novembre 2011 à 13:40:35

                      C'est un peu le principe de ce forum. :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Zeste de Savoir, le site qui en a dans le citron !
                        16 novembre 2011 à 15:09:14

                        mdr ouai je sais pas certain forum t'as une réponse qui marche pas et quant tu redemande de l'explication personne te répond ^^

                        Sinon est-il possible de défiler du texte dans un bouton?

                        Exemple si on prend le bouton sur ce forum répondre au sujet. Est-il possible que le texte " Répondre au sujet" défile de droite vers la gauche par exemple?
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          16 novembre 2011 à 20:23:46

                          Bon je peux enfin répondre ce post m'a un peu travaillé toute la journée.

                          Citation

                          Sachant que mon crea_raccourcis(filename) retourne une fonction qui ne prend pas d'argument, je vois mal ce qui pourrait poser problème... tu serais pas embrouillé par le fait sur ma fonction retourne une autre fonction, par hasard ?



                          On arrête tout de suite, j'ai considéré le code du PO et non le tiens.

                          En ce qui concerne le code du PO, j'étais sûr à presque 100% que se serait fonctionnel.

                          Ton code, ayant pas testé, je n'en n'étais pas certains, mais j'ai jamais utilisé une fonction avec argument sans utiliser la fonction anonyme lambda, et pourtant j'ai utilisé Tkinter pendant un long moment.
                          Mais je te rassure pas, car je n'ai toujours pas testé, par contre le PO peut tenter.

                          Citation

                          Est-il possible que le texte " Répondre au sujet" défile de droite vers la gauche par exemple?



                          Je ne pense pas que Tkinter soit suffisamment évolué pour faire ce genre de choses, à moins d'avoir loupé quelquechose.

                          @Nohar, Edit : J'avais un gros doute, qui vient de se confirmer en lisant ceci ;)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            16 novembre 2011 à 21:41:56

                            Citation : fred1599

                            Ton code, ayant pas testé, je n'en n'étais pas certains, mais j'ai jamais utilisé une fonction avec argument sans utiliser la fonction anonyme lambda, et pourtant j'ai utilisé Tkinter pendant un long moment.



                            Non mais les deux expressions sont strictement équivalentes.
                            La façon dont je m'y prends (en utilisant une fonction définie explicitement dans une fonction d'ordre supérieur plutôt qu'une lambda) permet juste de créer une abstraction entre le code de la GUI et celui de l'action qui est effectuée, ce qui permet de séparer le code "métier" de l'affichage, et donc de pouvoir développer et maintenir les deux indépendamment l'un de l'autre, voilà tout.

                            Du reste :

                            def ma_fonction(argument):
                                def commande():
                                    truc(argument)
                                return commande
                            
                            # est équivalent à 
                            
                            def ma_fonction2(argument):
                                return lambda: truc(argument)
                            
                            # donc
                            
                            ma_fonction(argument)
                            
                            # est équivalent à 
                            
                            lambda: truc(argument)
                            


                            • Partager sur Facebook
                            • Partager sur Twitter
                            Zeste de Savoir, le site qui en a dans le citron !
                              16 novembre 2011 à 21:48:53

                              mdr j'ai testé les deux et les deux marches :)
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Anonyme
                                16 novembre 2011 à 21:50:08

                                Ok je m'incline, mais ta solution (créer une fonction dans une fonction, genre de decorateur) me semble bien plus compliqué qu'une simple lambda. Enfin je trouve ça plus lisible à mon sens.

                                Mais ton code, j'admet doit être fonctionnel
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  17 novembre 2011 à 6:16:34

                                  Bonjour les gars je suis vraiment vraiment dsl de vous déranger encore une fois pour un problème similaire mais je ne sais pas comment faire encore une fois :/

                                  je colle mon code d'abord et j'explique le probleme:

                                  for filename in mes_racc:
                                                  #crée un bouton avec le chemin du filename
                                                  btnRajouter =Tkinter.Button(group_input.interior(),text=nom, command = lambda : self.crea_raccourci(filename))
                                                  if self.col == 3:
                                                      self.col = 0
                                                      self.lign = self.lign+1
                                                      btnRajouter.grid(column = self.col,row = self.lign)
                                                  else:
                                                      self.col = self.col +1
                                                      btnRajouter.grid(column = self.col, row = self.lign)
                                  


                                  mes_racc est la liste crée par la lecture d'un fichier txt et grace à split(';')

                                  (le fichier contient les chemins des différent raccourcis séparé par des ; )

                                  filename est donc l’élément 1 puis l’élément 2 etc de la liste mes_racc c'est donc à chaque fois un nouveau chemin. J'ai bien vérifier si c'est le cas en mettant un print(filename) au début de la boucle for ,il m'affichais bien un chemin différent à chaque fois.

                                  le problème vient seulement à la fin de la boucle for. Il colle le même chemin pour tout les boutons qu'il à lui même crée, à chaque fois le dernier chemin de la liste mes_racc. Vous voyez ce que je veux dire? ^^ donc je comprend pas comment c'est possible vu que lui même m'affiche des chemins différent quand je fais print(filename).

                                  pour le crea_raccourci c'est le même que celui de ce que j'avais collé avant avec os.startfile

                                  Merci encore une fois. ^^

                                  J'ai pensé aussi à faire un def ,juste avant la boucle , qu'on appellerait dans la boucle pour faire les raccourcis à partir d'un autre endroit que la boucle for. Mais ça me fait le même problème.

                                  Mais dans le programme qu'on j'ajoute un raccourci au moment même j'ai beau en faire 10 mille les raccourcis auront leur propre chemin donc je vois pas le soucis :/

                                  le seul truc que je sais c'est que le problème survient qu’après la lecture du fichier.

                                  Si vous avez besoin du code entier je peux vous le passer mais il fait un peu plus de 100 lignes ..
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    18 novembre 2011 à 7:41:00

                                    ah c'estb on j'ai trouvé j'ai changer mon crea_raccourci en ca:

                                    def crea_raccourci(self,filename):
                                            racc = lambda : os.startfile(filename)
                                            return racc
                                    


                                    Et dans command du bouton je fais appel du coup à crea_raccourci et ça marche
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Anonyme
                                      18 novembre 2011 à 10:14:46

                                      J'ai vraiment du mal à suivre tes explications, ton histoire de lambda et je pense que tu devrais revoir des bases python avant de continuer car tu vas rentrer dans un mur dans très peu de temps.

                                      Essaies aussi d'utiliser des modules, fonctions,... qui sont portables.

                                      Ensuite arrive le net, des exemples d'utilisation de command avec le widget Button, il y en a une sacré pelleté.

                                      Mais avant de créer un code python en utilisant un framework, tu devrais commencer par les bases ;)

                                      J'utiliserais correctement un framework que si j'ai des débuts de notions en POO, est-ce ton cas, j'en doute.

                                      Bon amusement
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Problème gestion raccourci

                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                      • Editeur
                                      • Markdown