Bonjour,

Peut être un rajout à faire dans la FAQ. C'est un basique mais bon...

Pourquoi j'obtiens le message _tkinter.TclError: image "pyimage1" doesn't exist ?

Pour commencer une petite explication du fonctionnement de l'instance Image de Tkinter:

Lors de la création d'une première instance Tk celle ci deviens le root par défaut.
Lors d'une création d'une instance Image (instance PhotoImage, BitmapImage ou une instance compatible comme pour ImageTk du module PIL par exemple) celle ci est associée au root par défaut et, si son nom n'est pas spécifié via l'option name, elle est nommée pyimageX (ou X est un nombre incrémenté à chaque création d'instance d'image pour une même instance Tk).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
>>> import tkinter
>>> root = tkinter.Tk()
>>> img = tkinter.PhotoImage(file='exemple.gif')
>>> img.name
'pyimage1'
>>> img1 = tkinter.PhotoImage(file='exemple1.gif', name='exemple1')
>>> img1.name
'exemple1'
>>> root.image_names()
'exemple1 pyimage1'
Lorsque vous utilisez l'option image d'un Widget, ou le create_image d'un Canvas, ce n'est pas le nom que vous lui avez donner sous Python qui est gardé en référence mais son nom interne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
>>> import tkinter
>>> root = tkinter.Tk()
>>> img = tkinter.PhotoImage(file='exemple.gif')
>>> lab = tkinter.Label(root, image=img)
>>> lab.config('image')
('image', 'image', 'Image', '', 'pyimage1')
>>> lab.cget('image')  # 'pyimage1' et non img
'pyimage1'
C'est ce nom qui est donné lors de l'erreur.

L'erreur image "nom_de_limage" doesn't exist interviens lorsque plusieurs instances Tk sont présentes et que celle à qui l'on fait référence n'est pas celle à qui l'image est associée.
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
>>> import tkinter
>>> root = tkinter.Tk()
>>> otherroot = tkinter.Tk()
>>> img = tkinter.PhotoImage(file='exemple.gif')
>>> lab = tkinter.Label(otherroot, image=img)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/tkinter/__init__.py", line 2462, in __init__
    Widget.__init__(self, master, 'label', cnf, kw)
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1961, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage1" doesn't exist
>>> otherroot.image_names()
''
>>> root.image_names()
'pyimage1'
Le fait d'avoir plusieurs instances Tk peut avoir deux origines:

- Vous utilisez des instances Tk pour vos fenêtres secondaires et dans ce cas vous devez plutôt utiliser des instances Toplevel pour celles-ci.

- Vous utilisez un IDE écrit avec Tkinter, IDLE par exemple, et le root par défaut est l'instance Tk de votre IDE car c'est la première créée. Dans ce cas vous devez spécifier l'instance Tk à utiliser avec l'option master de l'instance Image:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
>>> import tkinter
>>> root = tkinter.Tk()  # Disons que c'est votre IDE
>>> myroot = tkinter.Tk()
>>> img = tkinter.PhotoImage(file='exemple.gif', master=myroot)
>>> lab = tkinter.Label(myroot, image=img)
>>> lab.pack()
Dans tous les cas l'utilisation des Toplevel pour les fenêtres secondaires et le fait de spécifier l'option master sont des pratiques plus que fortement recommandées.

Note: Cette FAQ ne tiens pas compte du fait que vous devez garder une référence à votre image
Votre avis ?

@+