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 :

Image Cliquable sur Canvas


Sujet :

Tkinter Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut Image Cliquable sur Canvas
    Bonjour a tous,

    Je plante un peu le décor, j'utilise python 2.7 avec Tkinter et le tout sur Linux pour faire un petit logiciel de Gestion d'un Stock Perso.

    Pour l'instant, j'ai crée le Menu, et les images sur le Canvas mais je n'arrive pas du tout a les faire devenir Cliquable.


    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
    # -*- coding: utf-8 -*-
    from Tkinter import *
    from PIL import Image,ImageTk
    import tkMessageBox
     
     
    class FenPrincipale:
        def __init__(self):
            """Constructeur de la fenetre principale"""
            #Creation de la fenetre principale
            self.root = Tk()
            ##################################
     
     
            #Affichage fond et icone        
            self.can = Canvas(self.root, bd=10,relief=RIDGE)
     
            self.imgFond = PhotoImage(file="Images/Icones/font.gif")
            self.can.create_image(300,225,image=self.imgFond)        
     
            self.imageQuitter = Image.open("Images/Icones/Quitter.png")        
            self.imgQuitter = ImageTk.PhotoImage(self.imageQuitter)
            self.Quitter = self.can.create_image(100,100,image=self.imgQuitter)
     
            self.can.pack()
            ######################################################################
     
     
            # Affichage de la fenetre et bouclage
            self.root.mainloop()
            self.root.destroy()
            ##############################################
     
     
    # Programme principal
    if __name__ == '__main__':
        FenPrincipale()
    #########################"""
    J'ai tenté de faire un [...].bind([...]) ça n'existe pas avec une image.

    J'ai aussi tenté faire un bouton, intégré l'image dedans mais comme mon image est ronde, le tour reste gris comme le bouton est gris or le bouton ne gère pas la transparence.

    Puis j'ai pensé a réaliser un Frame qui serait devant tout le reste pour pouvoir obtenir les coordonnées x, y pour gérer les cliques mais la Frame n'est pas transparente et je n'arrive a la faire devenir transparente.

    Verdict, j'ai des idées mais rien ne fonctionne

    J'en viens donc a votre aide, comment feriez vous?

    Merci


    PS : Bien sur j'ai plus d'image normalement, la j'ai uniquement laissé celle pour quitter

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Si vous voulez rendre un item du canvas "clickabe", il faut lui associer des événements et des actions via .tag_bind. Et cela est, à priori, "valable" pour n'importe quel item crée dans le canvas.

    Dans la pratique, il faut stocker l'identifiant ou associer un tag à l'item créé par .create_XXX:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    deleteBtn = cnv.create_image(10, 10, image=icons('action_delete'))
    puis faire le .tag_bind... sur deleteBtn.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cnv.tag_bind(deleteBtn, '<1>', do_action_delete)
    Ici, çà dit d'appeler la fonction do_action_delete lorsqu'on clique sur mouse button 1

    Et voilà
    - W

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Wow! Super efficace!

    Je demandais pas mieux qu'une seule ligne pour faire ce que je voulais

    Merci beaucoup wiztricks

    De la même façon, il n'existerait pas une commande pour changer l'apparence du pointeur de la souris lorsqu'elle passe sur l'image "clikable" ?

    le [...]create_image([...],cursor='fleur') ne fonctionne pas

    Merci encore

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Citation Envoyé par punky591 Voir le message
    De la même façon, il n'existerait pas une commande pour changer l'apparence du pointeur de la souris lorsqu'elle passe
    Le cursor est une option du widget/window (ici canvas).
    Si vous voulez changer l'apparence du "cursor" lorsqu'il passe sur certains items, "il suffit" d'associer des events/commandes à un "tag", ici "toggle_cursor":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cnv.tag_bind('toggle_cursor', '<Enter>', lambda e: cnv.configure(cursor = 'hand1'))
    cnv.tag_bind('toggle_cursor', '<Leave>', lambda e: cnv.configure(cursor=''))
    Puis d'associer ce tag aux items qui vous intéressent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    deleteBtn = cnv.create_image(10, 10, image=icons('action_delete'), tag='toggle_cursor')
    Ici lors de la création mais cela peut être fait et défait à d'autres moments.

    - W

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Bonjour

    Encore une fois... Merci!

    Ça fonctionne exactement comme je le veux

    Très bonne explication wiztricks

    D'ailleurs, comment savez-vous tout cela? Il existe un site ou tout est répertorié? Ou puis-je apprendre tout cela?

    Le seul truc bien que j'ai trouvé c'est ca : http://www.tutorialspoint.com/python/tk_canvas.htm

    Dans le cas présent, ça explique les options du Canvas, mais rien de ce que vous m'avez montré.

    Comment se procurer de telles informations?

    Merci encore

    Bonne journée!

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    D'ailleurs, comment savez-vous tout cela? Il existe un site ou tout est répertorié? Ou puis-je apprendre tout cela?

    Dans le cas présent, ça explique les options du Canvas, mais rien de ce que vous m'avez montré.
    Sur le wiki de python.org sont répertoriées la plupart des documentations/tutoriels sur tkinter.

    Je n'ai pas de recommandation particulière: çà dépend de ce que vous voulez faire et de votre "background".

    Personnellement, lorsque je cherche quelque chose, je regarde plutôt Tkinter reference: a GUI for Python et surtout le manuel TCL/Tk

    Mais cela ne vous montre pas comment "utiliser" les widgets, pour cela il faut lire des codes déjà écrits ou des exemples: effbot est pas mal, le tutorial de tkdocs est aussi très bien.
    Vous avez aussi des contributions genre http://tkinter.unpythonic.net/wiki/ ou encore des codes écrits en TCL à l'url

    Bon courage
    - W

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut Clique Image et Clique Bouton
    Bonjour a tous

    Je reviens vers vous car j'ai encore un petit problème avec mon programme, en fait plusieurs problème, je m'explique :

    Pour commencer je souhaiterais avoir votre avis sur mon programme. j'entends par votre avis si vous trouver que la façon dont je rédige mon programme est correct. J'entends beaucoup parler des classes donc je m'y suis mis dès le début mais je vois que j'ai encore des trucs pas claire dans ma tète. Voici mon programme que j'ai réduis (300 lignes a la base)

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    # -*- coding: utf-8 -*-
    from Tkinter import *
    from PIL import Image,ImageTk
    import tkMessageBox
    import wx
     
     
     
    class FenPrincipale:
        def __init__(self):
            """Constructeur de la fenetre principale"""
            self.root = Tk()
            self.can = Canvas(self.root,width = 600, height = 450, bd=10,relief=RIDGE)
            self.can.tag_bind('toggle_cursor', '<Enter>', lambda e: self.can.configure(cursor = 'hand1'))
            self.can.tag_bind('toggle_cursor', '<Leave>', lambda e: self.can.configure(cursor=''))
     
            self.imageCategorie = Image.open("Images/Icones/CercleCategorie.png")
            self.imageCategorie.thumbnail((100, 100), Image.ANTIALIAS)
            self.imgCategorie = ImageTk.PhotoImage(self.imageCategorie)
            self.Categorie = self.can.create_image(455,230,image=self.imgCategorie,tag='toggle_cursor')
            self.can.tag_bind(self.Categorie,'<Button-1>',FenCategorie)
     
            Button(self.root,text='Categorie',command=FenCategorie).pack()
            Button(self.root,text='Quitter',command=self.root.quit).pack()
     
            self.can.pack()
     
            self.root.mainloop()
     
        def rayQuit(self,event=None):
            self.root.quit()
     
     
    class FenCategorie:
        def __init__(self,event=None):
            """Constructeur de la fenêtre principale"""
            #Creation de la fenetre principale
            self.rootC = Toplevel()
            self.rootC.geometry("%dx%d+%d+%d" %(180,250,(self.rootC.winfo_screenwidth()-180)/2,(self.rootC.winfo_screenheight()-250)/2))
            self.rootC.resizable(width=False, height=False)
            self.rootC.title('Catégorie')
     
     
            #Creation du Menu
            self.menuG = Menu(self.rootC)
            self.menufichier = Menu(self.menuG,tearoff = 0)
            self.menufichier.add_command(label = "Quitter",command=self.rootC.destroy)
     
            self.menuG.add_cascade(label="Fichier", menu=self.menufichier)
     
            self.rootC.config(menu=self.menuG)
     
     
            #Affichage fond et icone
            self.can = Canvas(self.rootC,width = 180, height = 250, bd=10,relief=RIDGE)
     
            self.imagePhoto = Image.open("Images/Icones/fontCategorie.png")
            self.imagePhoto.thumbnail((310,310), Image.ANTIALIAS)
            self.imgPhoto = ImageTk.PhotoImage(self.imagePhoto)
            self.can.create_image(90,125,image=self.imgPhoto)
     
            self.can.pack()
     
     
     
     
    # Programme principal
    if __name__ == '__main__':
        FenPrincipale()
    Ma classe FenPrincipale est la première affichée. A partir de celle ci, je peux en ouvrir 5 autres. Dans mon exemple, je peux ouvrir uniquement la fenêtre FenCategorie qui est une classe (Pour l'info, toutes mes fenêtres vont gérer une même base de données (sqlite) ).

    Ma question est pourquoi j'arrive a appeler la Classe FenCategorie a partir de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.can.tag_bind(self.Categorie,'<Button-1>',FenCategorie)
    mais qu'a partir du Bouton (ligne 23)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Button(self.root,text='Categorie',command=FenCategorie).pack()
    ca ne fonctionne pas?

    Une autre question est que lorsque j'ouvre la fenêtre FenCategorie je n'arrive pas a afficher l'image de font nommée 'fontCategorie.png'
    (Surtout que si je met self.rootC.mainloop() a la fin de la classe FenCategorie ca s'affiche mais alors après ça fait n'importe quoi quand je quitte les fenêtres.

    Jusqu'a maintenant je pensais avoir bien compris les classes mais en fait je crois que non

    En plus J'utilise IDLE qui utilise python, ça génère des erreurs avec les fenêtres. Donc je suis passé sur SPE, et la c'est le logiciel qui plante tout seul. Bref, vous utilisez quoi comme logiciel.

    Pour résumer :
    ==> Code correct en général?
    ==> Appel d'une classe différente entre Button et tag.bind d'une image?
    ==> IDLE/SPE/?

    Je pose beaucoup de question je le sais mais j'ai vraiment envie de parvenir a réaliser le logiciel, donc merci beaucoup d'avance a toute l'aide que vous pourrez m'apporter.

    Bonne après midi a tous

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Ma question est pourquoi j'arrive a appeler la Classe FenCategorie a partir de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.can.tag_bind(self.Categorie,'<Button-1>',FenCategorie)
    mais qu'a partir du Bouton (ligne 23)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Button(self.root,text='Categorie',command=FenCategorie).pack()
    ca ne fonctionne pas?
    Comment vous expliquer?

    Chaque fois que vous passez une fonction/callback à Tkinter, celui ci va l'emballer dans une structure adhoc. C'est cette "structure" qui sera en fait passée à Tk et qui sera éventuellement appelée.

    Le soucis est que si avec .tag_bind "on sait" qu'on va avoir une fonction, dans le dictionnaire text=..., command=... passé à Button, Tkinter ne va pas regarder "command" mais si la valeur associé à la clé a l'attribut __call__.

    Problème: FenCategorie peut être considéré comme "callable" mais n'a pas, en Python 2, d'attribut __call__ => la structure n'est pas crée et l'appel ne se fait pas.

    Ce comportement a été corrigé avec Python 3 au sens ou FenCategorie a un attribut __call__.
    => Pourquoi faire de nouveaux codes avec une vieille version de Python?

    Pour la question concernant "afficher l'image de font nommée 'fontCategorie.png'" impossible de comprendre ce que vous dites sans "reproducteur" dit autrement, après avoir modifié votre code pour que çà tourne, j'ai plus de problème mais j'ai aussi viré le .png, PIL etc...

    En plus J'utilise IDLE qui utilise python, ça génère des erreurs avec les fenêtres. Donc je suis passé sur SPE, et la c'est le logiciel qui plante tout seul. Bref, vous utilisez quoi comme logiciel.
    J'utilise emacs et de moins en moins Netbeans.
    Excepté pour les bricos et du debug, je préfère lancer mes scripts en mode "console". C'est généralement l'environnement "cible" et çà m'évite de me palucher des tonnes de docs pour assurer la cohérence entre IDE, console sur différents OS.

    J'entends beaucoup parler des classes donc je m'y suis mis dès le début mais je vois que j'ai encore des trucs pas claire dans ma tète.
    Pour l'instant vous avez des classes "conceptuelles" qui correspondent à ce que vous voulez qu'il se passe à l'écran: FenPrincipale et FenCategorie.

    Mais, tout étant (ou pourrait être) dans __init__, ce ne sont que de "grosses" fonctions qui créent les widgets Tk.
    note: les seules variables "utiles" sont les références aux images.

    Ceci dit, il faut bien un début.

    Vous pourriez éventuellement:
    • éviter "from Tkinter import *" et préférer "préfixer" via "import Tkinter as tk"
    • FenCategorie pourrait hériter de tk.Toplevel plutôt qu'emballer un Toplevel
    • virer toutes les variables d'instances qui ne servent à rien.
      Exemple: pourquoi mémoriser menuG dans self? Une fois le menu construit, çà ne sert à rien (enfin pour l'instant, plus tard... c'est à voir mais laissons venir ce plus tard...)
      Certes en Python, si un objet n'est pas référencé par une variable, le garbage collector le détruira...
      Mais lorsque vous créez des objets Tk, tkinter et Tk gardent la référence pour vous. L'objet ne sera "détruit" que si .destroy appelé directement ou via le .destroy du "master". Ne créez d'attribut que pour les objets dont vous aurez "vraiement" besoin plus tard (en attendant d'avoir appris à les récupérer dans event ou dans la hiérarchie des widgets tk).

      Notez que les image Tk doivent recevoir un traitement "différent" mais vous pourriez stocker l'image dans l'instance du canvas en créant l'attribut "on the fly", style:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
              canvas = Canvas(self.root,width = 600, height = 450, bd=10,relief=RIDGE)
              im = canvas.im = tk.PhotoImage(file="Images/Icones/CercleCategorie.png")
              canvas.create_image(455,230,image=im,tag='toggle_cursor')
      Mais il serait peut être plus sage de créer une "classe technique" Icons. qui permette de récupérer l'image en lui passant le nom du fichier et qui s'occupe de l'intendance.
    • L'event dans __init__ de FenCategorie n'est utile que pour permettre le déclenchement de:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      self.can.tag_bind(self.Categorie,'<Button-1>',FenCategorie)
      Si FenCategorie n'a pas besoin d'event, pourquoi ne pas écrire:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      self.can.tag_bind(self.Categorie,'<Button-1>', lambda e: FenCategorie)



    Bon courage

    - W

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Salut

    => Pourquoi faire de nouveaux codes avec une vieille version de Python?
    Je fais ca simplement parce que j'ai besoin de la librairie PIL pour afficher mes images qui ont pour extension png et/ou jpg. Et comme cette librairie n'a pas de version susceptible de fonctionner sur Python 3, j'ai rétrograder sur python 2.7.
    En plus j'ai appris avec le livre de G.Swinnen sur python 3 que tout le monde connaît apparemment,ça a fait 'drôle' de devoir passer en 2.7, il y a quelque changement tout de même.

    Je veux bien sans probleme repasser a la version 3, mais que pourrais-je utiliser pour afficher mes jpg ou png?

    Pour la question concernant "afficher l'image de font nommée 'fontCategorie.png'" impossible de comprendre ce que vous dites sans "reproducteur" dit autrement, après avoir modifié votre code pour que çà tourne, j'ai plus de problème mais j'ai aussi viré le .png, PIL etc...
    Je ne connais pas le terme de reproducteur de quoi s'agit-il?
    Je n'ai pas essayé sans librairie PIL de mon coté, je ferais ca dès demain mais si ca fonctionne avec Tk, pourquoi cela ne fonctionnerait pas avec PIL... A vérifier, je vous tiens au courant.

    J'utilise emacs et de moins en moins Netbeans.
    J'ai installé emacs, j'ai pas encore eu l'occasion de tester mais je donnerais des nouvelles aussi pour ca

    Pour l'instant vous avez des classes "conceptuelles" qui correspondent à ce que vous voulez qu'il se passe à l'écran: FenPrincipale et FenCategorie.

    Mais, tout étant (ou pourrait être) dans __init__, ce ne sont que de "grosses" fonctions qui créent les widgets Tk.
    note: les seules variables "utiles" sont les références aux images.
    Entendez vous par la que mettre toute la création de la fenêtre dans __init__ n'est pas une bonne chose?

    FenCategorie pourrait hériter de tk.Toplevel plutôt qu'emballer un Toplevel
    virer toutes les variables d'instances qui ne servent à rien.
    Pour les variables qui ne servent a rien je pensais faire le 'ménage' quand mes fenêtres serait toutes crées, pour y voir claire. C'etait prévu

    Par contre pouvez-vous s'il vous plais m'expliquer ce qu'est un emballage?
    Et pourquoi devoir herité de Tk.Toplevel? Je comprend que l'on s'en sert du Toplevel mais pourquoi est-ce plus 'simple' comme ça? La librairie Tkinter etant déjà importée tout au début du programme.

    Certes en Python, si un objet n'est pas référencé par une variable, le garbage collector le détruira...
    Euh... Quest-ce qu'un garbage collector?

    Si FenCategorie n'a pas besoin d'event, pourquoi ne pas écrire:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     self.can.tag_bind(self.Categorie,'<Button-1>', lambda e: FenCategorie)
    Malheureusement je connaissais ' lambda e: ' qu'a partir du moment ou vous l'avez montrer quelque post plus haut mais je ne sais pas réellement a quoi cela sert même si je l'utilise correctement dans mon programme

    Je pense vraiment que je vais revoir les cours sur les classes pour comprendre plus de chose que j'ai compris. Certaines lacunes sont handicapantes. Le site de sebsauvage me parait bien pour commencer.

    J'ai survolé les sites que vous m'avez conseillé. C'est vrai qu'il m'ont l'air bien complet, j'irais en détail dès demain également.

    Merci encore pour votre aide wiztricks, heureusement que les forums existent

    EDIT : J'ai tenté de mettre un fichier *.gif pour tester si mon image s'affiche et toujours rien
    Et Emacs fonctionne pour plusieurs langage non? Je ne trouve pas ou exécuter le programme

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Je fais ca simplement parce que j'ai besoin de la librairie PIL pour afficher mes images qui ont pour extension png et/ou jpg. Et comme cette librairie n'a pas de version susceptible de fonctionner sur Python 3, j'ai rétrograder sur python 2.7.
    Je n'utilise PIL que sous Windows et comme les libraries externes sont ch... à compiler je fais d'abord mon marché à http://www.lfd.uci.edu/~gohlke/pythonlibs/ avant de m'y résoudre.
    Et... La version 1.1.7 est dispo pour les versions 3.2 et 3.3.

    Je ne connais pas le terme de reproducteur de quoi s'agit-il?
    Un script minimal pour reproduire/illustrer le problème dont vous parlez. Un truc qui permette de toucher du doigt ce que vous racontez plutôt que d'interpréter vos mots.

    Entendez vous par la que mettre toute la création de la fenêtre dans __init__ n'est pas une bonne chose?
    Je disais que des classes quasi réduites à dérouler le contenu d'une méthode pourraient être de simples fonctions.

    Par contre pouvez-vous s'il vous plais m'expliquer ce qu'est un emballage?
    Et pourquoi devoir herité de Tk.Toplevel? Je comprend que l'on s'en sert du Toplevel mais pourquoi est-ce plus 'simple' comme ça? La librairie Tkinter etant déjà importée tout au début du programme.
    En écrivant "class FenCategorie(tk.Toplevel)", FenCategorie héritant de la classe tk.Toplevel devient "tk.Toplevel".
    L'héritage est une des associations basiques entre "classes".

    Dans votre cas, la boîte FenCategorie cache/emballe des références à des objets Tk. Techniquement FenCategorie est un agrégat (qui est une autre forme d'association "basique") parce que vous pouvez détruire l'instance ou ses éléments indépendamment.

    Problème.

    Dans votre construction, le callback associé à "command" ou le "bind", crée une instance de FenCategorie. Mais cette chose n'étant pas stockée, le garbage collector la détruira dès que possible (ainsi que la référence à l'image stockée dans l'attribut imgPhoto).
    En héritant de Toplevel, vous héritez d'une gestion du cycle de vie de l'instance qui sera cohérente avec l'objet Tk dont il hérite.
    Note: Essayez pour voir ce que devient _votre_ problème dans ce cas.

    Euh... Quest-ce qu'un garbage collector?
    C'est l'engin qui vous permet d'économiser au moins 20-30% du temps de développement d'une application et un temps indéfini passé à comprendre et corriger les bugs induits par la mise au point de votre propre gestion mémoire.
    Il gagne a être connu.

    - W

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Selon le site (officiel il me semble) de PIL, il est écrit qu'il n'existe pas de version pour python 3
    Sur le site que vous m'avez donné, il existe des fichiers zip. Pour linux j’espère, je verrais bien comment l'installer pour revenir sur la version 3. J’espère qu'il n'y aura pas beaucoup de modifications a faire.


    Merci pour l'info du terme reproducteur, j'en aurais pas besoin car j'ai résolu mon problème d'affichage d'image

    Je pense que le fait d’hériter de Tk.Toplevel pour Fen Catégorie et de Tk.Tk pour FenPrincipale y est pour quelque chose.


    Je suis tout a fait d'accord sur le fait que ça irait mieux de créer une classe Icons, ca serait plus claire dans mon programme.

    L'event dans __init__ de FenCategorie n'est utile que pour permettre le déclenchement de:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.can.tag_bind(self.Categorie,'<Button-1>',FenCategorie)
    Si FenCategorie n'a pas besoin d'event, pourquoi ne pas écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.can.tag_bind(self.Categorie,'<Button-1>', lambda e: FenCategorie)
    J'ai essayé d'ajouter le ' lambda e:' et bien sur d'enlever le 'event=None' dans FenCategorie mais ca n'a aucune réaction lorsque je clique sur l'image.

    Voici mon code pour les classes, j’espère qu'il est mieux qu'avant :

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import Tkinter as Tk
     
    class FenPrincipale(Tk.Tk):
        def __init__(self):
            Tk.Tk.__init__(self)
            self.initialize()
            self.mainloop()
     
        def initialize(self):
            FenCategorie()
    class FenCategorie(Tk.Toplevel):
        def __init__(self,event=None):
            Tk.Toplevel.__init__(self)
            self.initialize()
     
        def initialize(self):        
            pass
    if __name__ == "__main__":
        FenPrincipale()
    Je vais voir pour créer une classe Icons voir si j'y arrive puis ensuite je verrais pour passer a python3

    Bonne soirée!

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Je pense que le fait d’hériter de Tk.Toplevel pour Fen Catégorie et de Tk.Tk pour FenPrincipale y est pour quelque chose.
    Cela permet à vos instances d'avoir une durée de vie cohérente avec les objets tkinter dont ils héritent. Mais le seul effet (positif) est d'empêcher le GC de détruire la référence aux images dans les "attributs" associés aux instances.

    Joli comme effet de bord...

    Selon le site (officiel il me semble) de PIL, il est écrit qu'il n'existe pas de version pour python 3.
    Yup, çà à l'air toujours en chantier. La version que j'utilise est un port "non officiel".

    De toute façon Python 3 ou pas, ce qui précède montre qu'utiliser la "classe" comme "fonction" suppose stocker la référence à l'instance si on souhaite que la dite instance "survive" au delà de l'exécution de son __init__.

    En faisant hériter vos classes d'objets tkinter, on masque le problème...
    Qui est du à votre utilisation de Python "en général" car si vous ne stockez pas la référence à un objet (instance) quelque part, vous les laissez en pâture au "garbage collector"...

    A la limite, le reproducteur serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class A: 
        def __init__(self):
             self.im = 123
     
    def foo():
        a = A()
    Si 'foo' est la "commande" ou le "bind" tk qui crée un "A" vous imaginez bien qu'en sortie l'instance "a" n'a plus de raison d'être... et à fortiori l'objet 123 référencé par .im

    - W

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Bonjour

    Je viens pour pour le roman du jour


    Alors dans l'ordre j'ai remis mon programme en python 3 puis tenté d'installer PIL mais il ne fonctionne que sous windows d’après le site. Donc je suis reparti sur python 2.7. Bref.

    Donc comme j'avais dit, j'ai voulu créer la classe Icones. Raté.

    Je me suis dit qu'avant de faire un truc qui a l'air compliqué, je vais commencer par faire un truc 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
    import Tkinter as Tk
     
    class Fen1(Tk.Tk):
        def __init__(self):
            Tk.Tk.__init__(self)
            self.initialize1()
            self.mainloop()
     
        def initialize1(self):
            Fen2.b()
     
    class Fen2(Tk.Toplevel):
        def __init__(self):
            """Constructeur de la fenêtre principale"""
            Tk.Toplevel.__init__(self)
            self.initialize2()
     
        def initialize2(self):        
            print "initialisation"
     
        def b(self):
            print "b"
     
     
    if __name__ == "__main__":
        Fen1()
    Mais rien que ça, ça ne fonctionne pas non plus, d'habitude ce sont des circuits intégrés que je programme (en C), je pense que la logique n'est pas vraiment la même...

    J'avoue que sur ce point la, faire un appel de fonction en C est plus facile. Mais pour les interfaces graphiques c'est pas simple!

    Est-ce si compliqué de ça de faire appel a une méthode d'une autre classe dans le même fichier?

    De quoi devrait hériter la classe Icones au final?

    Je devrait chercher un autre livre pour les classes moi

    Merci encore

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Est-ce si compliqué de ça de faire appel a une méthode d'une autre classe dans le même fichier?
    Hmm

    En C vous n'avez pas de notion d'objet, juste des modules qui définissent des fonctions et des "struct"ures de données.

    En Python vous avez aussi des modules mais vous avez en plus des "classes".

    Les "classes" sont des sortes de modules puisqu'elles contiennent méthodes et structures de données.

    Il s'agit de méthode et non de "fonctions" car, par défaut, elles ont besoin du contexte d'une "instance" pour "fonctionner" (i.e. une définition du "self").
    Autrement dit, "par défaut" une classe est une sorte de "fabrique" d'objets semblables qu'on appelle "instances".

    De ce fait, lorsqu'on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     >>> class A(object):
    ...     def foo(self): print ('foo')
    ...
    Le self est une référence à l'instance (qui n'a pas encore été crée).
    Appeler la méthode "directement" produit l'erreur "explicite" (en 2.7):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> A.foo()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unbound method foo() must be called with A instance as first argument (got nothing instead)
    Il faut "créer" une instance "avant":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> a = A()
    >>> a.foo()
    foo
    Python étant "riche", on peut changer ce défaut et définir des méthodes de "classe" ou des méthodes "statiques". Dans ces cas, le premier argument de la fonction sera la classe ou rien du tout -- mais vous verrez cela un autre jour ;-)

    Ceci dit, comme tkinter définit déjà les classes pour vous, vous avez rarement besoin de construire vos propres classes: programmez comme en C avec des fonctions et des variables "globales" est largement suffisant.

    Python, Tk et la POO çà fait quand même beaucoup surtout que vous n'en avez pas encore besoin!

    - W

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Ah oui... je comprend mieux que ça ne fonctionnait pas,, En effet la fabrique a objet est une bonne idée

    Python, Tk et la POO çà fait quand même beaucoup surtout que vous n'en avez pas encore besoin!
    C'est pas la première fois que je me demande pourquoi j'utilise les classes, j'en ai pas vraiment besoin! Mais bon, autant apprendre tout d'un coup je me dis. Autant galérer d'un coup

    D'ailleurs il y a encore un phénomène que je ne comprend pas :

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import Tkinter as Tk
     
    class FenPrincipale(Tk.Tk):
        def __init__(self):
            Tk.Tk.__init__(self)
            self.initialize()
            self.mainloop()
     
        def initialize(self):
            FenCategorie()
    class FenCategorie(Tk.Toplevel):
        def __init__(self,event=None):
            Tk.Toplevel.__init__(self)
            self.initialize()
     
        def initialize(self):        
            self.can = Tk.Canvas(self,width = 180, height = 250, bd=10,relief=Tk.RIDGE)
     
            self.imagePhoto = Image.open("Images/Icones/fontCategorie.png")
            self.imagePhoto.thumbnail((310,310), Image.ANTIALIAS)
            self.imgPhoto = ImageTk.PhotoImage(self.imagePhoto)
            self.can.create_image(90,125,image=self.imgPhoto)
     
            Tk.Button(self.can,text="Catégorie disponible",command=self.destroy).grid(row=1,column=1,rowspan=2)
     
            self.can.pack()
    if __name__ == "__main__":
        FenPrincipale()
    Le problème ce coup ci est que lorsque je ne créer pas le bouton j'obtiens bien mon canevas mais a partir du moment ou je créer le bouton, c'est comme ci je n'avais pas mis de canvas

    J'ai un peu la poisse quand même

    Par contre ça me fait penser à une chose, quand j'appelle 'FenCategorie', je ne créer pas d'instance Donc j'en conclus que python le fait tout seul alors?

    Thanks

    EDIT : En fait ca fonctionne quand je met tout ce que j'ai a mettre sur le canvas. Sauf que que le Canvas se redimensionne selon les objets. Je vais voir ce que je peux faire

    Le menu déroulant est a venir aussi

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Citation Envoyé par punky591 Voir le message
    Le problème ce coup ci est que lorsque je ne créer pas le bouton j'obtiens bien mon canevas mais a partir du moment ou je créer le bouton, c'est comme ci je n'avais pas mis de canvas
    .grid, .pack, .canvas,... sont des "geometry managers". Et comme tous les managers ils n'aiment pas partager leur territoire définit ici par les "children" (enfin en gros).

    Par contre ça me fait penser à une chose, quand j'appelle 'FenCategorie', je ne créer pas d'instance Donc j'en conclus que python le fait tout seul alors?
    L'appel crée l'instance mais vous ne la stockez pas.
    Ca fonctionne parce que la classe hérite de Toplevel et tkinter fait le stockage de la référence pour vous.

    - W

  17. #17
    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,

    Pour ce qui est de l'image du Toplevel c'est une perte de référence:
    Celle de FenPrincipale s'affiche car elle est au même niveau de code que l'instance self.root mais pas celle du Toplevel.
    Vous devez la stocker explicitement.

    Grossièrement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            self.rootC.imgPhoto = ImageTk.PhotoImage(self.imagePhoto)
            self.can.create_image(90,125,image=self.rootC.imgPhoto)
    Ou encore
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class MyImages:
        Categorie = None
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            MyImages.Categorie = ImageTk.PhotoImage(self.imagePhoto)
            self.can.create_image(90, 125, image=MyImages.Categorie)
    Etc...
    Mais comme dit wiztricks 'qu'importe la boite'.

    @+

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut PauseKawa,

    Qu'avez vous voulu dire par:
    Citation Envoyé par PauseKawa Voir le message
    Pour ce qui est de l'image du Toplevel c'est une perte de référence:
    Celle de FenPrincipale s'affiche car elle est au même niveau de code que l'instance self.root mais pas celle du Toplevel.
    Nota, je râle parce que je ne comprends pas mais cela n'a pas d'importance.
    - W

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Développeur en électronique
    Inscrit en
    Mai 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur en électronique
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Salut tout le monde, c'est encore moi (Ca fesait longtemps )

    Merci pour l'explication de la classe Icones (ou myImages) pour commencer.
    Je pensais juste que ça allait réduire mon code mais apparemment pas vraiment.
    Je pensais a un "appel" de ce genre : MyImages(maitre,positionx,positiony,nom_de_l_Image)

    Enfin bon, pour l'instant je ne m'occupe pas de ca, mais plutot de l'affichage.

    Mon problème ce coup ci, est plutôt étrange. Toujours par rapport a ce qui est fait ci-dessus :

    Je creer une fenetre Principale ; Puis a partir de celle ci, j'en appel 5 autres ( grace a des classes qui hérite de Toplevel).

    A partir de cette deuxième, je crée un bouton (Une image cliquable en fait, mais ce n'est pas le problème) qui appelle une méthode dans laquelle il y a un tkMessageBox.showinfo.

    Le problème est que quand je clique sur le bouton, la Message box s'affiche devant ma fenêtre Principale, mais derrière ma Fenêtre Catégorie. Existe t-il un moyen de la faire apparaître devant?

    (Avant j'avais activé l'option overrideredirect mais cela force ma fenêtre a être modale. Ce que je ne veux pas.)

    Un code vaut mieux qu'un long discours :

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import Tkinter as Tk
    import tkMessageBox
    from PIL import Image,ImageTk
     
    class FenPrincipale(Tk.Tk):
        def __init__(self):
            Tk.Tk.__init__(self)
            self.geometry("%dx%d+%d+%d" %(600,450,(self.winfo_screenwidth()-600)/2,(self.winfo_screenheight()-450)/2))
            self.initialize()
            self.mainloop()
     
        def initialize(self):
            self.can = Tk.Canvas(self,width = 600, height = 450, bd=10,relief=Tk.RIDGE)
            self.can.tag_bind('toggle_cursor', '<Enter>', lambda e: self.can.configure(cursor = 'hand1'))
            self.can.tag_bind('toggle_cursor', '<Leave>', lambda e: self.can.configure(cursor=''))
     
            self.imageInfo = Image.open("Images/Icones/Info.png")
            self.imageInfo.thumbnail((20, 20), Image.ANTIALIAS)
            self.imgInfo = ImageTk.PhotoImage(self.imageInfo)
            self.Info = self.can.create_image(385,60,image=self.imgInfo,tag='toggle_cursor')
            self.can.tag_bind(self.Info,'<Button-1>',FenCategorie)
     
            self.can.pack()
     
    class FenCategorie(Tk.Toplevel):
        def __init__(self,event=None):
            Tk.Toplevel.__init__(self)
            self.geometry("%dx%d+%d+%d" %(200,200,((self.winfo_screenwidth()-200)/2),((self.winfo_screenheight()-200)/2)+28))
            self.initialize()
     
        def initialize(self):        
            Tk.Button(self,text="Info",command=self.Info).pack()
     
        def Info(self):
           	tkMessageBox.showinfo("Info","BlaBla")
     
     
     
    if __name__ == "__main__":
        FenPrincipale()
    Merci beaucoup

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 313
    Points : 36 819
    Points
    36 819
    Par défaut
    Salut,

    Pour que la toplevel associée au message apparaître "au dessus" de la toplevel qui l'affiche, vous pouvez renseigner "parent" ainsi:
    tkMessageBox.showinfo('info', 'blahblah', parent=self)
    - W

Discussions similaires

  1. Éparpiller images cliquables sur la page
    Par Alex-L dans le forum Webdesign & Ergonomie
    Réponses: 3
    Dernier message: 15/01/2011, 13h16
  2. [MySQL] Mettre une image cliquable sur un lien en PHP
    Par qmike dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 06/07/2010, 12h54
  3. Image cliquable sur écran tactile
    Par vincenze2000 dans le forum Java ME
    Réponses: 3
    Dernier message: 17/01/2009, 17h13
  4. Réponses: 1
    Dernier message: 05/08/2006, 20h43
  5. [Tkinter] Insérer une image jpg sur un canvas avec PIL
    Par Kyojimbo dans le forum Tkinter
    Réponses: 2
    Dernier message: 23/02/2006, 16h46

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