# Autres langages > Python > GUI >  problme d'affichage dune image avec Tkinter

## destroy51

Bonjour,
Je suis en train de programmer le jeu du cavalier en Python avec le module Tkinter.
Il marche trs bien mais je voudrais remplacer les ronds par des images gif et je n'y arrive pas... A l'aide !!!

J'ai remplac ma ligne :
 can.create_oval(x-r, y-r, x+r, y+r, fill='red')

par

photo=PhotoImage(file= "toto.gif")
can.create_image(400,400,image=photo)

mon fichier toto.gif tant dans le mme rpertoire que mon programme.
Je n'ai pas de message d'erreur mais rien ne s'affiche, pourquoi?
merci de votre aide.

----------


## psyphi

Merci d'utiliser la balise code quand tu postes du code dans le forum.
Essaye avec "./toto.gif". Nmaoins tu devrais faire un test de l'existence du fichier image avant d'essayer de l'ouvrir.

----------


## destroy51

Dsol pour la balise, je suis nouveau sur le forum.
Merci pour ta rponse, mais comment je peux faire un test de l'existence du fichier image?

----------


## psyphi

```

```

----------


## destroy51

Je viens de rajouter les 2 lignes de codes.
J'ai une erreur : argument should be string, bytes or integer, not PhotoImage
mais oh surprise, mon image est sur l'chiquier.
Si ma dduction est bonne, cela voudrait dire qu'il l'affiche bien mais qu'elle disparait aussitt...
Que dois-je faire pour qu'elle ne disparaisse pas ?

----------


## wiztricks

Salut,




> Que dois-je faire pour qu'elle ne disparaisse pas ?


Si vous ne montrez pas plus de code que:


```

```

On peut juste penser que photo est variable locale d'une fonction.
Un truc comme:


```

```

devrait "mieux" fonctionner.

Le truc est que photo (instance de PhotoImage) tant dtruite a la sortie de la fonction, il n'y aura plus d'image a afficher. 
- W

----------


## destroy51

Super,
a marche !!!
Encore merci pour toutes les infos...

----------


## destroy51

J'ai un nouveau problme...
Lorsque mon cheval se dplace sur l'chiquier, il laisse une bouse dans la case prcdemment occupe...
a marche pour le premier dplacement mais pour le second dplacement la 1re bouse disparait, et ainsi de suite...
Alors que je voudrais que toutes les bouses restent sur l'chiquier.
Voici la partie du code correspondante qui se trouve dans une fonction :




```
photo2=PhotoImage(file="bouse.gif")
```



```
dic['photo2']=photo2
```



```
can.create_image(cx,cy,image=photo2)
```



```
photo1=PhotoImage(file="cheval.gif")
```



```
dic['photo1']=photo1
```



```
can.create_image(x,y,image=photo1)
```

Pourquoi mes bouses disparaissent au fur et  mesure?

----------


## destroy51

Dsol pour la MEP, je viens juste de piger l'utilisation de la balise... Ce sera mieux comme a :
J'ai un nouveau problme...
Lorsque mon cheval se dplace sur l'chiquier, il laisse une bouse dans la case prcdemment occupe...
a marche pour le premier dplacement mais pour le second dplacement la 1re bouse disparait, et ainsi de suite...
Alors que je voudrais que toutes les bouses restent sur l'chiquier.
Voici la partie du code correspondante qui se trouve dans une fonction :



```

```

Pourquoi mes bouses disparaissent au fur et  mesure?

----------


## wiztricks

Salut,
Si vous ne postez pas un peu de code qui permette de reproduire le problme, je ne sais pas.
Ceci dit, si "dic" est local, c'est pas la peine de chercher non plus.

- W

----------


## destroy51

Voici mon programme :



```

```

----------


## wiztricks

Ah ouais.... Une succession d'appels qui execute:


```

```

est plutt os.

Daprs vous, si la case dic['photo2'] stocke une rfrence a une instance de PhotoImage(file="bouse.gif").
Que deviendra cette rfrence lorsque vous aller y stocker l'instance suivante?

"bougez" ces instructions juste aprs:


```

```

Dans le callback "pointeur(event)", les appels a .create_image pourront avoir image=dic['photo2X'].
Pourquoi prendre la peine de stocker vos PhotoImage dans un dict "global" si c'est pour devoir les recrer a chaque fois?

- W

----------


## destroy51

Magnifique, tout fonctionne  merveille...
Vous tes super fort en programmation !!!
Encore merci pour tous vos conseils.
Voici mon code final :


from tkinter import *  # pour utiliser des graphiques
from random import *  # pour gnrer des nombres alatoires


dic={}


# Fonction qui permet de calculer les coordonnes des sommets opposs d'une ligne en partant du point de coordonnes(0;y) #
def sommets(y):
    x=0
    liste=[]
    while x<1120:
        liste.append([x,y,x+70,y+70])
        x=x+70
    return liste


# Fonction qui permet de dessiner l'chiquier #
def recommencer():
    # Dessiner le damier
    global x,y,cx,cy,damier,listoccup,compteur,cheval

    # Initialisation des variables
    x=0
    y=0
    compteur=1   # variable qui compte le nombre de coups effectus
    listoccup=[0]*64  # liste qui gre l'occupation d'une case
    # Effacer le dessin prcdent:
    can.delete(ALL)


    # Definition de la matrice du damier
    damier=[]
    while y<560:
        damier.append(sommets(y)) # on remplit avec les coordonnes des sommets des cases de la ligne
        y=y+70
    a=0
    while a<8: # on trace la premiere partie du damier

        al=damier[a]
        b=0
        while b<8:
            al1=al[b]
            can.create_rectangle(al1[0],al1[+1],al1[2],al1[3],fill='black')  # dessine un carr noir
            b=b+2   
        a=a+2
    a=1
    while a<8: # on recommence avec un dcalage de 1 en abcsisse et de 1 en ordonne pour la deuxieme partie du damier

        al=damier[a]
        b=1
        while b<8:
            al1=al[b]
            can.create_rectangle(al1[0],al1[+1],al1[2],al1[3],fill='black')  # dessine un carr noir
            b=b+2   
        a=a+2

    # Affichage du contour de l'chiquier
    can.create_line(0,3,560,3,width=3,fill='brown')
    can.create_line(3,0,3,560,width=3,fill='brown')
    can.create_line(0,560,560,560,width=3,fill='brown')
    can.create_line(560,3,560,560,width=3,fill='brown')

    # Placer le cavalier de dpart de manire alatoire
    aleax=randrange(8) # on slectionne une position au hasard sur la matrice
    aleay=randrange(8)
    ligne=damier[aleax] # on prend les coordonnes alatoires
    case=ligne[aleay]
    x=case[0]+35  # on calcule l'abscisse du centre de la case
    y=case[1]+35  # on calcule l'ordonne du centre de la case
    cheval=can.create_image(x,y,image=photo1)  # on dessine le cheval
    cx=x
    cy=y
    listoccup[int((x-35)/70)+8*int((y-35)/70)]=1  # on indique que la case est devenu occupe
    etiquette.configure(text="Nombre de cases restantes : "+str(64-compteur)) # affichage du compteur   







# Fonction qui teste si le dplacement est possible  partir de la position (x;y) #
def tester(x,y):
        caselibre=False
        if x>=105 and y>=175 and listoccup[int((x-105)/70)+8*int((y-175)/70)]==0:     # teste si le dplacement (-1;-2) reste dans l'chiquier et si la case cible est vide
            caselibre=True
        if x<=455 and y>=175 and listoccup[int((x+35)/70)+8*int((y-175)/70)]==0:      # teste si le dplacement (+1;-2) reste dans l'chiquier puis si la case cible est vide
            caselibre=True
        if x<=385 and y>=105 and listoccup[int((x+105)/70)+8*int((y-105)/70)]==0:     # teste si le dplacement (+2;-1) reste dans l'chiquier puis si la case cible est vide
            caselibre=True
        if x<=385 and y<=455 and listoccup[int((x+105)/70)+8*int((y+35)/70)]==0:      # teste si le dplacement (+2;+1) reste dans l'chiquier puis si la case cible est vide
            caselibre=True
        if x<=455 and y<=385 and listoccup[int((x+35)/70)+8*int((y+105)/70)]==0:      # teste si le dplacement (+1;+2) reste dans l'chiquier puis si la case cible est vide
            caselibre=True
        if x>=105 and y<=385 and listoccup[int((x-105)/70)+8*int((y+105)/70)]==0:     # teste si le dplacement (-1;+2) reste dans l'chiquier puis si la case cible est vide 
            caselibre=True
        if x>=175 and y<=455 and listoccup[int((x-175)/70)+8*int((y+35)/70)]==0:      # teste si le dplacement (-2;+1) reste dans l'chiquier puis si la case cible est vide   
            caselibre=True
        if x>=175 and y>=105 and listoccup[int((x-175)/70)+8*int((y-105)/70)]==0:     # teste si le dplacement (-2;-1) reste dans l'chiquier puis si la case cible est vide
            caselibre=True
        if caselibre==False :
            if compteur==64 :
                can.create_text(300,250,font=('Ravie',50),text="BRAVO !!!",fill='blue')
            else :
                can.create_text(300,250,font=('Ravie',50),text="PERDU !!!",fill='blue')



# Fonction qui dessine un cheval dans la case ou clique l'utilisateur si le coup est possible bien entendu et laisse une bouse dans la case prcdente...#
def pointeur(event):
    global cx,cy,listoccup,compteur,caselibre,cheval
    x=event.x%70
    x=(event.x-x)+35   # x est l'abscisse du centre de la case ou clique l'utilisateur
    y=event.y%70
    y=(event.y-y)+35   # y est l'ordonne du centre de la case ou clique l'utilisateur

    if abs(cx-x)==140 and abs(cy-y)==70 and listoccup[int((x-35)/70)+8*int((y-35)/70)]==0  :   # teste si le dplacement est correct et si la case cible est vide    
        can.delete(cheval)
        can.create_image(cx,cy,image=photo2)  # on dessine la bouse
        cheval=can.create_image(x,y,image=photo1)  # on dessine le cheval
        cx=x
        cy=y
        compteur+=1
        listoccup[int((x-35)/70)+8*int((y-35)/70)]=1   # on indique que la case est devenu occupe
        etiquette.configure(text="Nombre de cases restantes : "+str(64-compteur)) # affichage du compteur
        tester(x,y) # test fin de partie



    if abs(cx-x)==70 and abs(cy-y)==140 and listoccup[int((x-35)/70)+8*int((y-35)/70)]==0 :   # teste si le dplacement est correct et si la case cible est vide
        can.delete(cheval)
        can.create_image(cx,cy,image=photo2)  # on dessine la bouse
        cheval=can.create_image(x,y,image=photo1)  # on dessine le cheval
        cx=x
        cy=y
        compteur+=1
        listoccup[int((x-35)/70)+8*int((y-35)/70)]=1   # on indique que la case est devenu occupe
        etiquette.configure(text="Nombre de cases restantes : "+str(64-compteur)) # affichage du compteur
        tester(x,y)  # test fin de partie



# Programme principal : #
global damier

# creation d'une fenetre
fenetre = Tk()
photo2=PhotoImage(file="bouse.gif")
dic['photo2']=photo2
photo1=PhotoImage(file="cheval.gif")  
dic['photo1']=photo1
fenetre.title('jeu du cavalier par Jean-Luc Bosser')
can = Canvas(fenetre, width =560, height =560, bg ='white')
can.bind("<Button-1>", pointeur)
can.pack()

# creation d'un bouton
b1 = Button(fenetre, text ='recommencer', command =recommencer)
b1.pack(side =LEFT, padx =3, pady =3)

# creation d'une variable Tkinter
calcul=StringVar()

# creation d'une etiquette
etiquette=Label(fenetre)
etiquette.pack()

# lancer la procdure
recommencer()

# attente des evenements
fenetre.mainloop()Si vous voyez une amlioration possible du code, je suis preneur...

----------


## destroy51

Je me suis un peu loup dans les balises...dsl



```

```

----------


## wiztricks

Salut,
Si vous vous plantez dans lcriture d'un post, pas la peine de reposter: vous pouvez le modifier - regardez les "boutons" proposes par l'IHM - s'il n'est pas trop vieux (3 jours je crois).
- W

----------

