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 :

dictionnaire créé à l'extérieur de la fonction pour afficher l'item


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 18
    Points : 11
    Points
    11
    Par défaut dictionnaire créé à l'extérieur de la fonction pour afficher l'item
    Bonjour à tous,
    Je débute en tkinter.
    J'ai compris comment afficher un item (photo) via command d'un bouton en utilisant un dictionnaire extérieur à ma fonction liée à command mais je n'ai pas compris pourquoi ça marchait ainsi et pourquoi ça ne marchait pas sans le dictionnaire

    J'ai lu quelque part (ici) "garbage collector a détruit la variable avant qu'elle ne soit stockée dans un objet"

    Mais ça reste obscur pour moi puisque tout à l'air de rester dans la fonction

    Pourriez vous s'il vous plait m'expliquer le mécanisme particulier ?

    D'avance merci.

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Citation Envoyé par flcarnot2013 Voir le message
    J'ai compris comment afficher un item (photo) via command d'un bouton en utilisant un dictionnaire extérieur à ma fonction liée à command mais je n'ai pas compris pourquoi ça marchait ainsi et pourquoi ça ne marchait pas sans le dictionnaire

    Pas trop sûr de comprendre ce que tu veux dire par là.

    Un exemple de code sera bienvenu.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par flcarnot2013 Voir le message
    Mais ça reste obscur pour moi puisque tout à l'air de rester dans la fonction
    Les objets associés aux variables locales sont "déréferencés" à la sortie de la fonction.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def foo():
         ...
         image = PhotoImage(...)
         tk.Label(image=image)
    A la sortie de "foo", l'objet associé à "image" sera "détruit".
    Et on ne verra pas l'image dans le Label.

    Avec un dictionnaire "extérieur", on stocke l'objet dans une boîte qui ne sera pas détruire à la sortie de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def foo():
         ...
         dico['une clé'] = image = PhotoImage(...)
         tk.Label(image=image)
    Et çà pourra "fonctionner".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Merci pour cette réponse rapide.
    J'ai compris je pense la portée des variables en python mais dans l'exemple proposé Label() n'est-il pas lui même un objet local qui devrait être détruit ?

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par flcarnot2013 Voir le message
    J'ai compris je pense la portée des variables en python mais dans l'exemple proposé Label() n'est-il pas lui même un objet local qui devrait être détruit ?
    Mon tk.Label, contrairement à image, n'est pas assigné à une "variable locale".
    Mais lorsque vous créez un widget, il sera stocké en référence dans le dictionnaire "children" du widget "parent" qui par défaut est "root". Il ne sera détruit que par un appel explicite à la méthode .destroy.

    => Portée des variables et durée de vie des objets sont associés mais on ne parle pas de la même chose.

    Une vraie question pourrait être "et pourquoi Label(image=image) n'incrémente pas le nombre de référence?" mais bon...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Voila il me manquait cette notion de dictionnaire (global on va dire pour faire simple) pour les widgets .
    Je laisse de côté la "vraie"question . Je suis satisfait de cette vraie réponse à cette fausse question.

    Merci beaucoup.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Bonjour

    Je reviens finalement sur la "vraie" question.

    Si j'ai bien compris

    Le label a une référence dans un dictionnaire (children) et donc est globalement liée au root.

    Son "contenu" ( ses attributs ?) doit donc être global ce qui n'est pas le cas de image dans foo.

    En passant par dico la référence de image devient globale et ça fonctionne.

    Si je comprends la "vraie" question est (sans utiliser dico) pourquoi bien que label soit un objet lié à root il n'est pas reconnu comme un nouvel objet (si son "contenu" reste local) ?

    Est-cela ? Et donc Pourquoi ?

    D'avance merci

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par flcarnot2013 Voir le message
    Si je comprends la "vraie" question est (sans utiliser dico) pourquoi bien que label soit un objet lié à root il n'est pas reconnu comme un nouvel objet (si son "contenu" reste local) ?
    Il faut imaginer Tkinter comme une sorte de passerelle qui assure la correspondance entre "objets" Python et les "choses" TCL/Tk
    => Créer/détruire un objet Python doit entraîner création/destruction de la chose TCL/Tk associée.
    Dans le cas d'une PhotoImage, lorsqu'on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> import tkinter as tk
    >>> root = tk.Tk()
    >>> image = tk.PhotoImage(file='edit_16x16.gif')
    >>> image.name
    'pyimage1'
    On crée l'objet Python PhotoImage associé à la variable TCL/Tk "pyimage1".
    Les choses se compliquent avec "tk.Label(image=image).pack()"
    En fait on se contente d'expédier les commandes suivantes à l'interpréteur TCL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> root.tk.call(('label', '.label', '-image', image.name))
    <window object: '.label'>
    >>> root.tk.call(('pack', '.label'))
    ''
    >>>
    Bon d'accord, côté Python: on a aussi créé une instance de Label, fabriqué un identifiant et stocké l'association dans le children de parent.
    Mais pour ce qui est de l'image, on a juste passé la chaîne de caractère de l'identifiant TCL sans créer de référence à l'objet PhotoImage.

    Une image peut être associée à différents objets TCL/Tk comme les items d'un Canvas, des Labels,...
    Cette association est réalisée entre objets TCL/Tk dans le monde TCL/Tk, tkinter se contente de passer le nom de la chose TCL/Tk associée à l'image.
    Problème: comme TCL/Tk ne maintient pas le nombre de références à une "image", impossible de savoir quand la chose TCL/Tk n'est plus référencée et détruire l'objet côté Python (et TCL/Tk).

    Il a été choisi de détruire l'image TCL/Tk dès la destruction de l'objet tkinter PhotoImage.

    Le boulot de comptage de référence n'est pas fait côté TCL/Tk, on pourrait écrire du code côté Python.
    Si c'est "simple" pour des Labels, çà devient "compliqué" dans le cas d'items d'un Canvas: ils n'ont aucune existence côté Python.
    Comme "compliqué" <=> beaucoup de code et pas mal de bugs.
    Il faut arbitrer sur "est ce raisonnable compte tenu des cas d'utilisation d'une Image d'écrire une telle horreur?".

    La plupart du temps les image sont des fichiers spécifiques à l'application: fond d'écran, icônes,...
    Vous les chargez au démarrage de l'application ou "à la demande" une fois pour toute ou pas.
    Et vous allez avoir un dico. global pour les icons et autre gadgets ne serait-ce que pour dissocier les noms internes à l'application de ceux des fichiers externes.
    Pour les cas marginaux, on peut toujours stocker l'image dans l'objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> label = tk.Label(image=image)
    >>> label._image = image
    >>>
    La référence sera supprimée avec le Label.

    A vous de trouver le plus adapté à votre cas.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup pour cette réponse très précise

    En résumé long is the road à parcourir pour moi dans la compréhension de ces subtilités

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

Discussions similaires

  1. Fonction pour afficher un compteur
    Par auberstar dans le forum GTK+ avec C & C++
    Réponses: 10
    Dernier message: 23/04/2010, 11h10
  2. Réponses: 5
    Dernier message: 01/02/2010, 10h25
  3. [Dates] Fonction pour afficher les dernières news
    Par Justone22 dans le forum Langage
    Réponses: 23
    Dernier message: 04/08/2008, 22h57
  4. Fonction pour afficher une image
    Par philippef dans le forum Langage
    Réponses: 4
    Dernier message: 31/08/2007, 19h07
  5. Réponses: 9
    Dernier message: 17/02/2006, 11h04

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