Bonsoir,

Je devrais peut etre poster dans le forum général débutant..
Mais comme ma question concerne mes essais pour découvrir Tkinter, j'essaie sur ce forum.
Ma question n'en reste pas moins celle d'un débutant (vieux ) essayant d'apprendre (avec enthousiasme ).
Ne m'assassinez pas... du moins pas trop vite
Donc, je bricole un petit jeu naïf où il faut cliquer sur une image qui se déplacera tous les x temps me permet de jouer avec des widgets etc..

Une image sera chargée par défaut "atome.gif"
Mais en voulant placer un menu, puis faire changer l'image à apparaître via ce menu, je me rends compte que je sais pas comment m'y prendre pour que l'appel, qui se fait depuis le menu (via une lambda: ) de la fonction du choix d'image selectImage(nomFichier), ne se morde pas la queue avec la création du PhotoImage(fichier=fichierImage)...

Q1: Que me conseilleriez-vous, avec cette configuration (bancale?), pour pouvoir changer d'image via le menu?
PS: j'ai essayé de commenter le code.. ne pas se moquer hein :p
Dans tous les cas merci pour votre temps et toute forme d'aide ou de conseil
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
from tkinter import *
from random import randrange
 
#-----------------------------------------------------------------------------#
# Au début, dans cette fonction, on a n=nb (callback du boutonGo). On déclare
# aussi nb comme variable globale. Car n sera utilisé comme variable locale
# pour verifier si partie en cours, boucler les rappels de cette fonction
# après un delai can.after(..,n-1). Et nb pour comparer a n et voir si c'est
# une nouvelle partie qui vient d'être lancée via le boutonGo...
# Pas sûr ce que ce soit bien "propre" de faire des trucs comme ça.... :-s
#-----------------------------------------------------------------------------#
def afficher(n):
    global nb, cpt, clic
    can.delete('all')      # "nettoyage" du canevas
 
    # récuperer la valeur du cursseur de délais le transformer en milliseconde
    delai=int(cursDelai.get()*1000)
 
    # si n>0  on a une partie en cours
    if n>0:
 
        # si n=nb c'est une nouvelle partie. On en met les compteurs à 0
        if n==nb:
            cpt=0
            clic=0
 
        # on utilse les dimension de l'image pour definir la zone du canevas 
        # où l'im age apparaitra entière.
        a=imgPunch.width()
        b=imgPunch.height()
        x1ImpZone=int(a/2)
        x2ImpZone=int(canWidth-a/2)
        y1ImpZone=int(b/2)
        y2ImpZone=int(canWidth-b/2)
 
        # selection aléatoire de x et y dans la zone d'impression
        x=randrange(x1ImpZone, x2ImpZone)
        y=randrange(y1ImpZone, y2ImpZone)
        # creation de l'image a x, y (centre de l'image) avec un tag
        can.create_image(x,y,image=imgPunch, tags="tagImgPunch")
        #après un delai reappeler la fonction avec un n à n-1
        can.after(delai, afficher, n-1)
 
 
def touche(event):
    global cpt, clic
    x, y = event.x, event.y # recupère les cords du clic
    clic+=1 # incrémenter le compeur de clic
 
    # faire une petit cercle noir sur le clic (si on loupe la zone de l'image)
    can.create_oval(x-5,y-5,x+5,y+5, fill="black")
 
    # recuperer les coord de l'image (son centre)
    posImg=can.coords("tagImgPunch")
    # recuperer l'argeur et hauteur de l'image
    a=imgPunch.width()
    b=imgPunch.height()
 
    # definir s'il y a eu touche i.e. clic x,y dans la zone qui encadre l'image
    if (x>(posImg[0]-a/2))and(x<(posImg[0]+a/2))and(y>(posImg[1]-b/2))and(y<(posImg[1]+b/2)):
        # si oui faire un petit cercle rouge centré sur le clic x,y
        can.create_oval(x-5,y-5,x+5,y+5, fill="red")
        cpt+=1 # incrémenter le compteur de touche
 
 
#-----------------------------------------------------------------------------#
# Puis je / Dois je  utiliser une fonction pour changer le nom du fichier
# image de mon prog? Si oui comment faire ?...
#-----------------------------------------------------------------------------#
def selectImage(nomFichier):
    global fichierImg
    fichierImg=nomFichier
    print(fichierImg) # pour tester qu'on arrive bien ici 
    return fichierImg
 
 
#---------------------------programme principal-------------------------------#
 
# faire une fenetre
fenetre = Tk()
 
# definir le menu et sous menus
menuBar = Menu(fenetre)
fenetre['menu'] = menuBar
 
sousMenu1 = Menu(menuBar, tearoff=0)
sousMenu2 = Menu(menuBar, tearoff=0)
 
menuBar.add_cascade(label='Fichier', menu=sousMenu1)
sousMenu1.add_command(label='Quitter', command=fenetre.destroy)
 
menuBar.add_cascade(label='Choix image', menu=sousMenu2)
sousMenu2.add_command(label='atome100x90', command=lambda: selectImage("atome.gif"))  #<------
sousMenu2.add_command(label='test', command=lambda: selectImage("test.png"))       
# NB: fichiers images au format .png testés par ailleurs et fonctionnent :)
 
# definir ce que seront les largeur et hauteur du canevas (zone de jeu)
canWidth=500
canHeight=500
# definir le nombre d'apparition de l'image (10 par défaut)
nb=10
# placer le compteur de clic à 0
clic=0
# placer le compteur de touche à 0
cpt=0
 
# créer le canevas
can=Canvas(fenetre,width=canWidth, height=canHeight, bg="ivory")
# lier le clic gauche de sourie a la fonction touche
can.bind("<Button-1>", touche)
can.pack() # le materialsier dans la fenetre
 
# on charge l'image
fichierImg="atome.gif"  # <------------ se mord la queue avec la fonction..non?
imgPunch=PhotoImage(file=fichierImg) # <-------
 
# on crée un curseur pour avoir differents delais (entre apparion de l'image)
cursDelai=Scale(fenetre, orient="horizontal", from_=0.1, to=2.0,
      resolution=0.1, tickinterval=0.1, length=400, label="Delai entre chaque apparition (seconde)")
cursDelai.set(1.0) # pré-placer le curseur su 1.0
cursDelai.pack() # materialiser le curseur
 
# la commande du boutonGo sera une fonction lambda pour pouvoir appeller
# la fonction afficher AVEC un paramtere nb
boutonGo = Button(fenetre, text='Go!', command=lambda: afficher(nb))
boutonGo.pack(side=LEFT, padx=5, pady=5)
 
# materialisation et lancement de la boucle de la fenetre
fenetre.mainloop()