Bonjour, j'ai un projet a faire et je n'y arrive plus, j'ai prévu quelques choses encore ou je n'aurais pas de problème mais la j'ai un gros problème, j'aimerais que quand on change de case le compteur se reset a 1, j'ai vu qu'on pouvait faire ca avec des widget mais j'ai essayé avec les coordonées de la souris. Voilà le code, il est pas du tout optimisé et a quelques erreurs. Si vous pouvez m'aider.
Je cherche a remettre a 0 le compteur quand on change de case et pourquoi pas si vous avez une idée de comment faire, ne pas autorisé le fait de cliquer dans les cases déjà pleine (les cases noir)
from tkinter import *
import time
import numpy as np
import tkinter.font as tkFont
grille = np.zeros((4,4), dtype=np.int)
fen = Tk()
fen.geometry("256x256")
fen.title("Sudoku")
fen.resizable(width=FALSE, height=FALSE) #Permet à ce que la fenetre ne soit pas redimensionnable
police = tkFont.Font(family='Helvetica', size=15, weight='bold')
valeurUtilisateur = tkFont.Font(family='Helvetica', size=17, weight='bold')
x = 2
y = 2
compteur = 0 #compteur
cpt=1
eventx = 0
eventy = 0
grillesNonModifiables = [grille[0][0],grille[0][1],grille[1][3],grille[2][0],grille[3][2],grille[3][3]]
#grillesModifiables = [grille[1][0],grille[3][0],grille[1][1],grille[0][2],grille[1][2],grille[2][2],grille[0][3],grille[2][3]]
grille[0][0]=2
grille[0][1]=4
grille[1][3]=2
grille[2][0]=3
grille[3][2]=1
grille[3][3]=3
#grille[0][3]=1 #pas affiché
def Coordonpoint(event):
global xCase
global yCase
event.x
event.y
xCase=np.trunc(event.x/62.5)
yCase=np.trunc(event.y/62.5)
"""def cpt(var):
global compteur
compteur+=(var)
return compteur
"""
def creationrectangle(event,couleur):
Coordonpoint(event)
C.delete("car")
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
def clicMolette(event):
global compteur
Coordonpoint(event)
if grille[xCase][yCase] == grille[xCase][yCase]: #Si on clic sur la meme case
C.delete("valeuruser")
C.delete("car")
creationrectangle(event,"red") #crée le carré pour montrer ou est l'utilisateur
compteur=0 #Quand supprimé, remet le compteur a 0 pour que le premier clic affiche 1
def clicDroit(event):
global eventx
global eventy
global compteur
creationrectangle(event,"blue")
if grille[xCase][yCase] == grille[xCase][yCase]:
if compteur > 1:
C.delete("valeuruser")
compteur-=1
grille[xCase][yCase]=compteur
if xCase or yCase != event.x/62.5 and eventy/62.5:
compteur=1
grille[xCase][yCase]=compteur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
eventx=event.x
eventy=event.y
def clicGauche(event):
global eventx
global eventy
global compteur
creationrectangle(event,"blue")
if grille[xCase][yCase] == grille[xCase][yCase]:
if compteur < 4:
C.delete("valeuruser")
compteur+=1
grille[xCase][yCase]=compteur
if event.x/62.5 and event.y/62.5 == eventx/62.5 and eventy/62.5:
compteur=1
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
eventx=event.x
eventy=event.y
C=Canvas(fen, height=256, width=256,bg='white')
C.pack()
for k in range(1,6):
if k in [1,3,5]:
C.create_line(0, x, 256, x, width="3")
if k in [1]:
C.create_line(0, x, 256, x, width="5")
C.create_line(0,x, 256, x)
x+=62.5
for k in range(1,6):
if k in [1,3,5]:
C.create_line(y, 0, y, 256, width="3")
if k in [1]:
C.create_line(y, 0, y, 256, width="5")
C.create_line(y,0, y, 256)
y+=62.5
x1= 35
y1= -26
for c in range(0,4):
y1+=62
for l in range(0,4):
Texte = C.create_text(x1, y1, anchor="center")
if grille[l,c]!=0: #vérification de la condition valeur différent de zéro
C.itemconfig(Texte, text=grille[l,c], font=police)
x1+=62
x1=35
C.bind('<Button-1>', clicGauche)
C.bind('<Button-3>', clicDroit)
C.bind('<Button-2>', clicMolette)
fen.mainloop()
"""Les pb
1 : Supprime tant que pas a 4 au clic gauche ou 1 au clic droit
2 : Se remet pas a 1 quand je change de case
"""
Une solution raisonnable est donnée sur stack overflow il s'agit de remplacer les rectangles que tu traces dans creation_rectangle() [L49] par la creation d'une classe Rectangle qui hérite d'une classe Tkinter et qui contient des méthodes on_enter et on_leave avec un binding des evenements dans le init Bonne chance !
- Edité par IQbrod 15 mai 2018 à 8:22:39
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
Bonjour, si j'ai bien compris, il faut que je crée une classe qui contient la création du rectangle (def) et des def on_enter et on_leave ?
Quand vous dites "avec un binding des evenements dans le init", vous pensez a une fonction __init__ ?
Autre chose, si le __init__ est dans la class, je ne peu pas mettre les bind, j'ai besoin qu'ils soient déjà la avant puisque cette class intervient après le clic gauche ou droit.
Désolé mais je ne comprend pas comment le faire, si il faut mettre le __init__ dans la fonction des clics ou quoi
Pour simplifier la chose (c'est plus complexe et complet que ça), tu peux te dire que __init__ est un constructeur de ta classe. Ici tu n'as pas mis de classe (contrairement au lien que j'ai partagé). C'est lorsque tu crées ton rectangle (ta case de sudoku) que tu vas venir lier (binder) l'évenement à une fonction.
ClémentPyt a écrit:
PS : Le self sert a quoi ?
Le self désigne l'objet (l'instance de la classe que tu est en train de créer).
Il faudrait plutot quelque chose comme ça, puisque le rectangle n'est pas un "vrai" objet (il est construit dans un canvas qui lui est un objet de type tk.Canvas)
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
from tkinter import *
import time
import numpy as np
import tkinter.font as tkFont
grille = np.zeros((4,4), dtype=np.int)
fen = Tk()
fen.geometry("256x256")
fen.title("Sudoku")
fen.resizable(width=FALSE, height=FALSE) #Permet à ce que la fenetre ne soit pas redimensionnable
police = tkFont.Font(family='Helvetica', size=15, weight='bold')
valeurUtilisateur = tkFont.Font(family='Helvetica', size=17, weight='bold')
x = 2
y = 2
global compteur
compteur = 0 #compteur
cpt=1
eventx = 0
eventy = 0
grillesNonModifiables = [grille[0][0],grille[0][1],grille[1][3],grille[2][0],grille[3][2],grille[3][3]]
#grillesModifiables = [grille[1][0],grille[3][0],grille[1][1],grille[0][2],grille[1][2],grille[2][2],grille[0][3],grille[2][3]]
grille[0][0]=2
grille[0][1]=4
grille[1][3]=2
grille[2][0]=3
grille[3][2]=1
grille[3][3]=3
#grille[0][3]=1 #pas affiché
class rectangle:
def __init__(self, event):
self.Carr.bind("<Leave>", self.on_leave)
def affichage(event, couleur):
Coordonpoint(event)
C.delete("car")
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
def on_leave(self, enter):
self.compteur=0
monRectangle=rectangle
def Coordonpoint(event):
global xCase
global yCase
event.x
event.y
xCase=np.trunc(event.x/62.5)
yCase=np.trunc(event.y/62.5)
"""def cpt(var):
global compteur
compteur+=(var)
return compteur
"""
def creationrectangle(event,couleur):
Coordonpoint(event)
C.delete("car")
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
def clicMolette(event):
global compteur
Coordonpoint(event)
if grille[xCase][yCase] == grille[xCase][yCase]: #Si on clic sur la meme case
C.delete("valeuruser")
C.delete("car")
creationrectangle(event,"red") #crée le carré pour montrer ou est l'utilisateur
compteur=0 #Quand supprimé, remet le compteur a 0 pour que le premier clic affiche 1
def clicDroit(event):
global eventx
global eventy
global compteur
creationrectangle(event,"blue")
if grille[xCase][yCase] == grille[xCase][yCase]:
if compteur > 1:
C.delete("valeuruser")
compteur-=1
grille[xCase][yCase]=compteur
if xCase or yCase != event.x/62.5 and eventy/62.5:
compteur=1
grille[xCase][yCase]=compteur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
eventx=event.x
eventy=event.y
def clicGauche(event):
global eventx
global eventy
global compteur
compteur+=1
monRectangle.affichage(event,"blue")
monRectangle.on_leave
""" creationrectangle(event,"blue")
C.delete("valeuruser")
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
"""
C=Canvas(fen, height=256, width=256,bg='white')
C.pack()
Carr=Canvas(fen, height=62.5, width=62.5)
Carr.pack()
for k in range(1,6):
if k in [1,3,5]:
C.create_line(0, x, 256, x, width="3")
if k in [1]:
C.create_line(0, x, 256, x, width="5")
C.create_line(0,x, 256, x)
x+=62.5
for k in range(1,6):
if k in [1,3,5]:
C.create_line(y, 0, y, 256, width="3")
if k in [1]:
C.create_line(y, 0, y, 256, width="5")
C.create_line(y,0, y, 256)
y+=62.5
x1= 35
y1= -26
for c in range(0,4):
y1+=62
for l in range(0,4):
Texte = C.create_text(x1, y1, anchor="center")
if grille[l,c]!=0: #vérification de la condition valeur différent de zéro
C.itemconfig(Texte, text=grille[l,c], font=police)
x1+=62
x1=35
C.bind('<Button-1>', clicGauche)
C.bind('<Button-3>', clicDroit)
C.bind('<Button-2>', clicMolette)
fen.mainloop()
"""Les pb
1 : Supprime tant que pas a 4 au clic gauche ou 1 au clic droit
2 : Se remet pas a 1 quand je change de case
"""
Voilà ce que j'ai maintenant, je ne vois pas comment dire a ma class que si je sors du rectangle il faut remettre le compteur a 0, désolé mais c'est la première fois que j'utilise des class. J'ai compris pour le __init__.
class rectangle:
def __init__(self, event):
self.Carr.bind("<Leave>", self.on_leave)
def affichage(event, couleur):
Coordonpoint(event)
C.delete("car")
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
def on_leave(self, enter):
self.compteur=0
monRectangle=rectangle
self.Carr n'est pas initialisé (on ne sait pas ce que c'est ... un rectangle ?) Tu dois faire allusion à ton canvas qu'il faut passer soit en attribut de ta classe "rectangle" soit en global.
De même pour C.
Pour construire une instance de classe on utilise
monRectangle = Rectangle()
Mais ici ton constructeur doit avoir un paramètre "event"
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
Il me semble que .Carr est initialisé ligne 112 par
Carr=Canvas(fen, height=62.5, width=62.5)
Je ne comprend pas bien le "Tu dois faire allusion à ton canvas qu'il faut passer soit en attribut de ta classe "rectangle" soit en global."
Quand vous dites en attribut de ta classe, vous voulez dire une fonction dans la class rectangle ?
Et dans votre exemple de construction d'instance, monRectangle est le constructeur ? Ou Rectangle est le constructeur ? (Pour savoir ou mettre le (event)
Je vous avous que je ne comprend pas très bien pour le moment mais merci :)
Il me semble que .Carr est initialisé ligne 112 par
Carr=Canvas(fen, height=62.5, width=62.5)
Je ne comprend pas bien le "Tu dois faire allusion à ton canvas qu'il faut passer soit en attribut de ta classe "rectangle" soit en global."
Quand vous dites en attribut de ta classe, vous voulez dire une fonction dans la class rectangle ?
Et dans votre exemple de construction d'instance, monRectangle est le constructeur ? Ou Rectangle est le constructeur ? (Pour savoir ou mettre le (event)
Je vous avous que je ne comprend pas très bien pour le moment mais merci :)
Je te conseille directement de suivre des tutos sur la programmation orientée objet (en python) comme celui ci, ou celui ci. Je pense qu'il répondra à beaucoup de questions et t'aidera grandement à compléter ton projet. Tu t'attaques à quelque chose d'assez complexe et sans avoir les notions de bases (classes/objets/attributs) c'est quasiment impossible d'obtenir un résultat convenable !
Bonne lecture
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
Bonjour, j'ai lu les tutos que tu m'as donné, je les avait déjà vu pour tout te dire mais j'ai fais l'effort de les relire pour mieux comprendre.
class rectangle(Frame):
def __init__(self):
Frame.__init__(self)
self.car=Canvas(self, fen, height=256, width=256,bg='white')
self.Carr.pack()
self.C.bind("<Leave>", self.on_leave)
def affichage(event, couleur):
Coordonpoint(event)
carre.delete("car")
create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
def on_leave(self, event):
print("Jeje")
self.compteur=0
Voila ma classe rectangle, j'ai un peu regardé et essayé de faire pareille que sur le lien que tu m'as donné au début (OverFlow). mais je me retrouve avec un message d'erreur "unknown option "-visual""... Des fois j'ai "-menu" et je ne comprend pas bien.
J'ai eu des problèmes avec les self, la déclaration de C (fait ligne 4) etc. J'ai maintenant un autre problème, si a la dernière ligne j'enlève les parenthèse ca marche mais c'est comme si la def on_leave etait pas relié au bind
monRectangle = rectangle
J'ai bien vu pour ça mais je ne comprend toujours pas
IQbrod a écrit:
Pour construire une instance de classe on utilise
monRectangle = Rectangle()
Mais ici ton constructeur doit avoir un paramètre "event"
Je me demandais, dans le self.C = canvas que tu as mis, je met la meme chose ou je dois mettre un canvas ?
Ca permet de lier l'attribut C à l'argument passé au constructeur (ici canvas). Donc normalement pas besoin de toucher.
ClémentPyt a écrit:
Et pour le #Rectangle, je le link avec le canvas ou le C.create_rectangle ?
C'est le problème que je soulevais au départ de ton projet :
IQbrod a écrit:
Il faudrait plutot quelque chose comme ça, puisque le rectangle n'est pas un "vrai" objet (il est construit dans un canvas qui lui est un objet de type tk.Canvas)
La solution proposée est plutôt compliquée. Je pense qu'une autre approche est envisageable. On peut binder le canvas entier avec le déplacement de souris ('<Motion>'). Par cela tu obtiens la position de ta souris sur ton canvas.
Il suffit ensuite de calculer quelle case est "courante" et d'afficher un rectangle par dessus (pour donner un effet de hover).
1. Calcul de la case courante
2. Si case après motion différente de la case courante : On efface l'ancien rectangle de hover On dessine le nouveau rectangle de hover
- Edité par IQbrod 24 mai 2018 à 13:15:51
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
J'ai nettoyé tout ça et ca marche presque, je n'ai juste plus la grille affiché, voila le code si tu veux essayer pour voir ce que ca fais :
#-----------------------------import------------------------------------------------------
from tkinter import * #On importe tout de Tkinter
import numpy as np #On importe numpy sous le nom de np pour que ce soit plus facile d'utilisation
import tkinter.font as tkFont # On importe les polices tkinter (les font) sous le nom de tkFont car tkinter.font ne marchait pas directement
#-----------------------------import------------------------------------------------------
#------------------------------Initialisation des variables-------------------------------------------------------
x = 2 #Initialisé a 2 pour que au début lors de la création de la grille on puisse voir la ligne
y = 2 #Initialisé a 2 pour que au début lors de la création de la grille on puisse voir la ligne
global compteur #Rend global le compteur qui est modifier par les clics
compteur = 0 #compteur initialisé a 0 pour que le premier clic soit = a 1
eventx = 0 #Initialisation obligatoire
eventy = 0 #Initialisation obligatoire
x1= 35
y1= -26
#------------------------------Initialisation des variables-------------------------------------------------------
#------------------------------Caractéristiques de la fenêtre et des polices-------------------------------------------------------
grille = np.zeros((4,4), dtype=np.int) #Déclaration d'une matrice numpy de dimensions 4*4 nommé grillle initialisé avec uniquement des zeros
fen = Tk() #Nomme la fenetre fen
fen.geometry("256x256") #Donne a la fenêtre une geometrie de 256x256 pixel
fen.title("Sudoku") #Donne comme nom (en haut a gauche de la fenêtre) Sudoku
fen.resizable(width=FALSE, height=FALSE) #Permet à ce que la fenêtre ne soit pas redimensionnable en hauteur et largeur
police = tkFont.Font(family='Helvetica', size=15, weight='bold') #Donne comme nom police de la famile Helvetica de taille 15 des cases près remplis
valeurUtilisateur = tkFont.Font(family='Helvetica', size=17, weight='bold') #Donne comme nom valeurUtilisateur de la famle Herlvetica de taille 17 pour les valeurs donner par l'utilisateur
photoAide = PhotoImage("souris.jpg")
C=Canvas(fen, height=256, width=256, bg='white') #Créer un Canvas nommé C de taille 256/256 pixels
C.pack()
Rectangle = Canvas(fen, height=62.5, width=62.5, bg="black")
Rectangle.pack()
#------------------------------Caractéristiques de la fenêtre et des polices-------------------------------------------------------
#------------------------------Fonction d'affichage de la grille-------------------------------------------------------
n=6
tailleligne = 64 * n
def taille(n,x,y):
grille = np.zeros((n,n), dtype=np.int) #Déclaration d'une matrice numpy de dimensions 4*4 nommé grillle initialisé avec uniquement des zeros
if n == 4:
fen.geometry("256x256") #Donne a la fenêtre une geometrie de 256x256 pixel
if n == 11:
fen.geometry("562x562") #Donne a la fenêtre une geometrie de 562x562 pixel
for k in range(1,6):
if k in [1,3,5]:
C.create_line(0, x, tailleligne, x, width="3")
C.create_line(y, 0, y, tailleligne, width="3")
if k in [1]:
C.create_line(0, x, tailleligne, x, width="5")
C.create_line(y, 0, y, tailleligne, width="5")
C.create_line(0,x, tailleligne, x)
C.create_line(y,0, y, tailleligne)
x+=62.5
y+=62.5
#------------------------------Fonction d'affichage de la grille-------------------------------------------------------
fenAide = Canvas(fen, width=462, height=462)
#------------------------------Menu-------------------------------------------------------
def aide(): #Fonction aide qui s'active après le clic sur le bouton aide
fenAide=Toplevel(fen, width=462, height=462) #Nouvelle fenêtre de dimension 462 pixels sur 462 pixels
imageAide = fenAide.create_image(fenAide, image=photoAide, anchor=center) #Création de l'image dans le canvas de 462/462 pixels
fenAide.pack()
menubar = Menu(fen)
menu1 = Menu(menubar, tearoff=0)
menu1.add_command(label="4x4", command=taille(4,x,y)) #Affiché une fois que le menu1 (Taille) est selectioné
menu1.add_command(label="9x9", command=taille(1,x,y)) #Affiché une fois que le menu1 (Taille) est selectioné
menu1.add_separator() #Affiché une fois que le menu1 (Taille) est selectioné et sépare les tailles avec quitter
menu1.add_command(label="Quitter", command=fen.destroy) #Affiché une fois que le menu1 (Taille) est selectioné, fais quitter la fenêtre
menubar.add_cascade(label="Taille", menu=menu1)
menu2 = Menu(menubar, tearoff=0)
menubar.add_command(label="Comment jouer", command=aide) #Sorte de bouton aide pour comment jouer
fen.config(menu=menubar)
#------------------------------Menu-------------------------------------------------------
#------------------------------Determination de la grille-------------------------------------------------------
#grillesNonModifiables = [grille[0][0],grille[0][1],grille[1][3],grille[2][0],grille[3][2],grille[3][3]]
#grillesModifiables = [grille[1][0],grille[3][0],grille[1][1],grille[0][2],grille[1][2],grille[2][2],grille[0][3],grille[2][3]]
grille[0][0]=2 #Case de la grille a x = 0 et y = 0 qui est égal a 2 (Première case)
grille[0][1]=4 #Case de la grille a x = 0 et y = 1 qui est égal a 4
grille[1][3]=2 #Case de la grille a x = 1 et y = 3 qui est égal a 2
grille[2][0]=3 #Case de la grille a x = 2 et y = 0 qui est égal a 3
grille[3][2]=1 #Case de la grille a x = 3 et y = 2 qui est égal a 1
grille[3][3]=3 #Case de la grille a x = 3 et y = 3 qui est égal a 3
#------------------------------Determination de la grille-------------------------------------------------------
#------------------------------Classe qui gère l'affichage au clic et le reset a 0 quand on change de case-------------------------------------------------------
class rectangle:
def __init__(self, fen, C):
#self.C = canvas
self.car = C
self.Carre = Canvas(fen, height=62.5, width=62.5, bg="red")
self.car.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
self.car.bind("<Leave>", self.on_leave) #Bind le fait que si on sort du rectangle déclanche la fonction on_leave
self.car.pack()
def affichage(self, event, couleur): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
def on_leave(self, event): #Fonction on_leave si on sort du rectangle
global compteur
print("Jeje")
compteur=0 #Reinitialise le compteur à 0 quand on sort du rectangle
monRectangle = rectangle(fen, C)
#------------------------------Classe qui gère l'affichage au clic et le reset a 0 quand on change de case-------------------------------------------------------
#------------------------------Fonctions en rapport avec la souris-------------------------------------------------------
def Coordonpoint(event):
global xCase
global yCase
event.x
event.y
xCase=np.trunc(event.x/62.5)
yCase=np.trunc(event.y/62.5)
def clicGauche(event):
global compteur
compteur+=1
monRectangle.affichage(event,"blue")
monRectangle.on_leave
fen.mainloop()
def clicMolette(event):
global compteur
monRectangle.affichage(event, "red")
compteur=0 #Quand supprimé, remet le compteur a 0 pour que le premier clic affiche 1
C.delete("valeuruser")
def clicDroit(event):
global eventx
global eventy
global compteur
creationrectangle(event,"blue")
if grille[xCase][yCase] == grille[xCase][yCase]:
if compteur > 1:
C.delete("valeuruser")
compteur-=1
grille[xCase][yCase]=compteur
if xCase or yCase != event.x/62.5 and eventy/62.5:
compteur=1
grille[xCase][yCase]=compteur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
eventx=event.x
eventy=event.y
#------------------------------Fonctions en rapport avec la souris-------------------------------------------------------
"""
for k in range(1,6):
if k in [1,3,5]:
C.create_line(y, 0, y, 256, width="3")
if k in [1]:
C.create_line(y, 0, y, 256, width="5")
C.create_line(y,0, y, 256)
y+=62.5
"""
for c in range(0,4):
y1+=62
for l in range(0,4):
Texte = C.create_text(x1, y1, anchor="center")
if grille[l,c]!=0: #vérification de la condition valeur différent de zéro
C.itemconfig(Texte, text=grille[l,c], font=police)
x1+=62
x1=35
taille(6,x,y)
C.bind('<Button-1>', clicGauche)
C.bind('<Button-3>', clicDroit)
C.bind('<Button-2>', clicMolette)
C.bind('<space>', clicMolette)
#VerificationGrille(grille,n)
fen.mainloop()
Et au fait, j'essaye de faire en sorte qu'une image s'ouvre quand on clic sur comment jouer mais l'image ne s'affiche pas. Si tu as une petite idée (J'ai changé de format et ça a pas marché non plus)
Merci a toi
Edit :
Quand je met self.Carre = Canvas(C,....) Ca marche mais je n'ai pas ma grille.
#-----------------------------import------------------------------------------------------
from tkinter import * #On importe tout de Tkinter
import numpy as np #On importe numpy sous le nom de np pour que ce soit plus facile d'utilisation
import tkinter.font as tkFont # On importe les polices tkinter (les font) sous le nom de tkFont car tkinter.font ne marchait pas directement
#-----------------------------import------------------------------------------------------
#------------------------------Initialisation des variables-------------------------------------------------------
x = 2 #Initialisé a 2 pour que au début lors de la création de la grille on puisse voir la ligne
y = 2 #Initialisé a 2 pour que au début lors de la création de la grille on puisse voir la ligne
global compteur #Rend global le compteur qui est modifier par les clics
compteur = 0 #compteur initialisé a 0 pour que le premier clic soit = a 1
eventx = 0 #Initialisation obligatoire
eventy = 0 #Initialisation obligatoire
x1= 35
y1= -26
#------------------------------Initialisation des variables-------------------------------------------------------
#------------------------------Caractéristiques de la fenêtre et des polices-------------------------------------------------------
grille = np.zeros((4,4), dtype=np.int) #Déclaration d'une matrice numpy de dimensions 4*4 nommé grillle initialisé avec uniquement des zeros
fen = Tk() #Nomme la fenetre fen
fen.geometry("256x256") #Donne a la fenêtre une geometrie de 256x256 pixel
fen.title("Sudoku") #Donne comme nom (en haut a gauche de la fenêtre) Sudoku
fen.resizable(width=FALSE, height=FALSE) #Permet à ce que la fenêtre ne soit pas redimensionnable en hauteur et largeur
police = tkFont.Font(family='Helvetica', size=15, weight='bold') #Donne comme nom police de la famile Helvetica de taille 15 des cases près remplis
valeurUtilisateur = tkFont.Font(family='Helvetica', size=17, weight='bold') #Donne comme nom valeurUtilisateur de la famle Herlvetica de taille 17 pour les valeurs donner par l'utilisateur
photoAide = PhotoImage("souris.jpg")
C=Canvas(fen, height=256, width=256, bg='white') #Créer un Canvas nommé C de taille 256/256 pixels
C.pack()
Rectangle = Canvas(fen, height=62.5, width=62.5, bg="black")
Rectangle.pack()
#------------------------------Caractéristiques de la fenêtre et des polices-------------------------------------------------------
#------------------------------Fonction d'affichage de la grille-------------------------------------------------------
n=6
tailleligne = 64 * n
def taille(n,x,y):
grille = np.zeros((n,n), dtype=np.int) #Déclaration d'une matrice numpy de dimensions 4*4 nommé grillle initialisé avec uniquement des zeros
if n == 4:
fen.geometry("256x256") #Donne a la fenêtre une geometrie de 256x256 pixel
if n == 11:
fen.geometry("562x562") #Donne a la fenêtre une geometrie de 562x562 pixel
for k in range(1,6):
if k in [1,3,5]:
C.create_line(0, x, tailleligne, x, width="3")
C.create_line(y, 0, y, tailleligne, width="3")
if k in [1]:
C.create_line(0, x, tailleligne, x, width="5")
C.create_line(y, 0, y, tailleligne, width="5")
C.create_line(0,x, tailleligne, x)
C.create_line(y,0, y, tailleligne)
x+=62.5
y+=62.5
#------------------------------Fonction d'affichage de la grille-------------------------------------------------------
fenAide = Canvas(fen, width=462, height=462)
#------------------------------Menu-------------------------------------------------------
def aide(): #Fonction aide qui s'active après le clic sur le bouton aide
fenAide=Toplevel(fen, width=462, height=462) #Nouvelle fenêtre de dimension 462 pixels sur 462 pixels
imageAide = fenAide.create_image(fenAide, image=photoAide, anchor=center) #Création de l'image dans le canvas de 462/462 pixels
fenAide.pack()
menubar = Menu(fen)
menu1 = Menu(menubar, tearoff=0)
menu1.add_command(label="4x4", command=taille(4,x,y)) #Affiché une fois que le menu1 (Taille) est selectioné
menu1.add_command(label="9x9", command=taille(1,x,y)) #Affiché une fois que le menu1 (Taille) est selectioné
menu1.add_separator() #Affiché une fois que le menu1 (Taille) est selectioné et sépare les tailles avec quitter
menu1.add_command(label="Quitter", command=fen.destroy) #Affiché une fois que le menu1 (Taille) est selectioné, fais quitter la fenêtre
menubar.add_cascade(label="Taille", menu=menu1)
menu2 = Menu(menubar, tearoff=0)
menubar.add_command(label="Comment jouer", command=aide) #Sorte de bouton aide pour comment jouer
fen.config(menu=menubar)
#------------------------------Menu-------------------------------------------------------
#------------------------------Determination de la grille-------------------------------------------------------
#grillesNonModifiables = [grille[0][0],grille[0][1],grille[1][3],grille[2][0],grille[3][2],grille[3][3]]
#grillesModifiables = [grille[1][0],grille[3][0],grille[1][1],grille[0][2],grille[1][2],grille[2][2],grille[0][3],grille[2][3]]
grille[0][0]=2 #Case de la grille a x = 0 et y = 0 qui est égal a 2 (Première case)
grille[0][1]=4 #Case de la grille a x = 0 et y = 1 qui est égal a 4
grille[1][3]=2 #Case de la grille a x = 1 et y = 3 qui est égal a 2
grille[2][0]=3 #Case de la grille a x = 2 et y = 0 qui est égal a 3
grille[3][2]=1 #Case de la grille a x = 3 et y = 2 qui est égal a 1
grille[3][3]=3 #Case de la grille a x = 3 et y = 3 qui est égal a 3
#------------------------------Determination de la grille-------------------------------------------------------
#------------------------------Classe qui gère l'affichage au clic et le reset a 0 quand on change de case-------------------------------------------------------
class rectangle:
def __init__(self, fen, C):
#self.C = canvas
self.Carre = fen
self.Carre = Canvas(C, height=62.5, width=62.5, bg="red")
self.Carre.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
self.Carre.bind("<Leave>", self.on_leave) #Bind le fait que si on sort du rectangle déclanche la fonction on_leave
self.Carre.pack()
def affichage(self, event, couleur): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
def on_leave(self, event): #Fonction on_leave si on sort du rectangle
global compteur
print("Jeje")
compteur=0 #Reinitialise le compteur à 0 quand on sort du rectangle
monRectangle = rectangle(fen, C)
#------------------------------Classe qui gère l'affichage au clic et le reset a 0 quand on change de case-------------------------------------------------------
#------------------------------Fonctions en rapport avec la souris-------------------------------------------------------
def Coordonpoint(event):
global xCase
global yCase
event.x
event.y
xCase=np.trunc(event.x/62.5)
yCase=np.trunc(event.y/62.5)
def clicGauche(event):
global compteur
compteur+=1
monRectangle.affichage(event,"blue")
monRectangle.on_leave
fen.mainloop()
def clicMolette(event):
global compteur
monRectangle.affichage(event, "red")
compteur=0 #Quand supprimé, remet le compteur a 0 pour que le premier clic affiche 1
C.delete("valeuruser")
def clicDroit(event):
global eventx
global eventy
global compteur
creationrectangle(event,"blue")
if grille[xCase][yCase] == grille[xCase][yCase]:
if compteur > 1:
C.delete("valeuruser")
compteur-=1
grille[xCase][yCase]=compteur
if xCase or yCase != event.x/62.5 and eventy/62.5:
compteur=1
grille[xCase][yCase]=compteur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser")
eventx=event.x
eventy=event.y
#------------------------------Fonctions en rapport avec la souris-------------------------------------------------------
"""
for k in range(1,6):
if k in [1,3,5]:
C.create_line(y, 0, y, 256, width="3")
if k in [1]:
C.create_line(y, 0, y, 256, width="5")
C.create_line(y,0, y, 256)
y+=62.5
"""
for c in range(0,4):
y1+=62
for l in range(0,4):
Texte = C.create_text(x1, y1, anchor="center")
if grille[l,c]!=0: #vérification de la condition valeur différent de zéro
C.itemconfig(Texte, text=grille[l,c], font=police)
x1+=62
x1=35
taille(6,x,y)
C.bind('<Button-1>', clicGauche)
C.bind('<Button-3>', clicDroit)
C.bind('<Button-2>', clicMolette)
C.bind('<space>', clicMolette)
#VerificationGrille(grille,n)
fen.mainloop()
def aide(): #Fonction aide qui s'active après le clic sur le bouton aide
fenAide=tk.Toplevel(fen) #Nouvelle fenêtre de dimension 462 pixels sur 462 pixels
MonCanvasImage = Canvas(fenAide,width=462, height=462)
#MonCanvasImage.create_image(fenAide, image=photoAide) #Création de l'image dans le canvas de 462/462 pixels
#MonCanvasImage.pack()
lab = MonCanvasImage.create_image(image=photoAide)
lab.pack()
def affichage(self, event, couleur): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
def aide(): #Fonction aide qui s'active après le clic sur le bouton aide
fenAide=tk.Toplevel(fen) #Nouvelle fenêtre de dimension 462 pixels sur 462 pixels
MonCanvasImage = Canvas(fenAide,width=462, height=462)
#MonCanvasImage.create_image(fenAide, image=photoAide) #Création de l'image dans le canvas de 462/462 pixels
#MonCanvasImage.pack()
lab = MonCanvasImage.create_image(image=photoAide)
lab.pack()
def affichage(self, event, couleur): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
C.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
Et j'appelle la méthode affichage ligne 122
- Edité par ClémentPyt 25 mai 2018 à 17:35:53
Non, tu créer la méthodes d'affichage de ta classe ligne 122, mais tu ne l'appelles pas (donc le code dedans ne s'execute jamais)
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
def clicGauche(event):
global compteur
compteur+=1
monRectangle.affichage(event,"blue")
monRectangle.on_leave
fen.mainloop()
Ici, monRectangle.affichage n'appelle pas la methode affichage ?
Voilà un correctif de ma fonction affichage mais cela n'affiche plus le rectangle
def affichage(self, event, couleur, Carre): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
Carre.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
Voilà un correctif de ma fonction affichage mais cela n'affiche plus le rectangle
def affichage(self, event, couleur, Carre): #Fonction affichage avec 2 paramètres, event qui sert pour les coordonées et couleur qui permet de choisir la couleur, bleu ou rouge (Dépend de quel clic)
Coordonpoint(event) #Récupère les coordonées de la souris au clic
C.delete("car") #Supprime le dernier rectangle qui sert de repère a l'utilisateur
Carre.create_rectangle(2+62.5*xCase,2+62.5*yCase,62.5*xCase+64.5,62.5*yCase+64.5, outline=couleur, width="3", tag="car") #crée le carré pour montrer ou est l'utilisateur
C.create_text(33.5+62.5*xCase,33.5+62.5*yCase, fill="grey", activefill="blue", text=compteur, font=valeurUtilisateur, anchor="center", tag="valeuruser") #Met dans la case la valeur du compteur qui augment ou diminue en fonction du clic
C n'existe pas dans ton contexte tu as accès à "self / event / couleur / Carre" ton Carre est inutile car tu y accèdes par self.Carre Et oui ton affichage est appelé
OpenClassrooms retire tellement d'aiguilles de nos pieds qu'on pourrait ne plus trouver le foin de notre botte :)
Un sudoku...
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Voilà ce que j'ai maintenant, je ne vois pas comment dire a ma class que si je sors du rectangle il faut remettre le compteur a 0, désolé mais c'est la première fois que j'utilise des class. J'ai compris pour le __init__.