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 :

Demande aide pour evenement sur widget Canvas


Sujet :

Tkinter Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 3
    Par défaut Demande aide pour evenement sur widget Canvas
    Bonjour tout le monde,

    Donc voila, mon but est de réaliser un jeu de picross (logigraphe) avec python, dans le code ci dessous, j'ai implémenté une fonction qui dessine une grille dans un widget Canvas. La grille est constitué de petits rectangles (qu'on peut leur affecter des id). Mon problerme est le suivant: etant novice en python (et en anglais aussi ) je cherche comment puis je implementer l'evenement clique souris qui permet de noircir une case (un rectangle du canvas) ou la dénoircir, c'est urgent, Merci d'avence pour vos réponses.

    Cordialement.

    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
     
    #-*- coding: utf-8 -*-
    from Tkinter import *
    #------------------------------------------------------------------------
    def Grille(fen,x,y):
        "Dessine la grille"
        taille_case=20
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
        i = 0
        while i < x:
            j = 0
            while j < y:
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white')
                j+=1
            i+=1
     
        canvas.pack()
     
    #------------------------------------------------------------------------
    root = Tk()
    Grille(root,25,25)
    root.mainloop()

  2. #2
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    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
    def Grille(fen,x,y):
        def onClick(event):
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
     
        "Dessine la grille"
        taille_case=20
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
        i = 0
        while i < x:
            j = 0
            while j < y:
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white')
                j+=1
            i+=1
     
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
    @+

    Edit: modif de lewidget en monitem.

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Petite explication quand même puisque j'ai 5 min:

    Lorsque tu clique tu crée un event qui a des coordonnées x, y
    Avec .canvasx(event.x) (et y) tu converti en coordonnées dans ton canvas
    Il ne te reste plus qu'a trouver (.find_closest) l'item qui se trouve a cette position. A noter que .find_closest retourne un tuple d'index mais comme pour .find_closest hallo=None de base cela ne retourne que l'index de l'item que tu recherche.
    .itemcget te permet de récupérer la valeur 'fill' de l'item en question et .itemconfigure (ou .itemconfig) de le modifier.

    Voili

    Bonne journée.

  4. #4
    Invité de passage
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1
    Par défaut
    Bonjour,

    Tout d'abord Merci pour votre réponse PauseKawa .

    Je suis embarrassé , ce n'est pas pour en abusé, mais à court d'idées, qu'est ce que vous me proposez pour que le petit (Canvas) "Aperçu" (voir code ci dessous) pourra suivre les modifications de la grille.

    Sinon pas de soucis, votre première réponse est dèja un grand pas pour que j'avance.

    Cordialement.

    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
     
    #-*- coding: utf-8 -*-
    from Tkinter import *
    #-------------------------------------------------------------------------------
    def Grille(fen,x,y):
        def onClick(event):
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
     
        "Dessine la grille"
        taille_case=20
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
        i = 0
        while i < x:
            j = 0
            while j < y:
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white')
                j+=1
            i+=1
     
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
    #-------------------------------------------------------------------------------
    def Apercu(fen,x,y):
        "Dessine l'aperçu"
        taille_case=5
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
        i = 0
        while i < x:
            j = 0
            while j < y:
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, outline='white',fill='white')
                j+=1
            i+=1
     
        canvas.pack()
    #-------------------------------------------------------------------------------
    root = Tk()
    Apercu(root,25,25)
    Grille(root,25,25)
    root.mainloop()

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Par défaut
    Bonjour,
    Voila une solution, qui ne me semble pas très propre mais qui fonctionne:
    Tout d'abord, il faut que tu es accès à ton canvas "apreçu" depuis fonction grille. Je l'ai donc mis en global et renommé canvas_ap.

    Ensuite il faut récupérer les coordonnés de la grille (i, j) en fonction des coordonnée du clique (x, y).
    Il suffit de diviser les cordonnées du clique par la taille de la case. Tu multiplies ensuite par la taille de la case de l'aperçu et tu peux alors récupérer l'item avec find_closest.

    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
     
    #-*- coding: utf-8 -*-
    from Tkinter import *
    #-------------------------------------------------------------------------------
     
     
     
    def Grille(fen,x,y, taille_case, taille_case_ap):
        def onClick(event):
     
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            x_app = (event.x -2) / taille_case * taille_case_ap
            y_app = (event.y -2) / taille_case * taille_case_ap
            monitem_ap = canvas.find_closest(canvas.canvasx(x_app), canvas.canvasy(y_app))
     
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
                canvas_ap.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
                canvas_ap.itemconfigure(monitem, fill='white')
     
        "Dessine la grille"
     
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
     
     
        for i in range(x):
            for j in range(y):
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white')
     
     
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
    #-------------------------------------------------------------------------------
     
     
     
     
    def Apercu(fen,x,y,taille_case):
        "Dessine l'aperçu"
     
        global canvas_ap
        canvas_ap = Canvas(fen, width =x*taille_case, height=y*taille_case)
     
        for i in range(x):
            for j in range(y):
                canvas_ap.create_rectangle((i*taille_case),(j*taille_case),((i+1)*taille_case) , ((j+1)*taille_case), outline='white',fill='white', width=0)
     
     
        canvas_ap.pack()
    #-------------------------------------------------------------------------------
    root = Tk()
    Apercu(root,25,25,5)
    Grille(root,25,25,20,5)
    root.mainloop()
    Une méthode (un peu) plus propre consisterait à passer les cordonnée (i, j) dans un tag qui servirait à récupérer l'item:

    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
     
    #-*- coding: utf-8 -*-
    from Tkinter import *
    #-------------------------------------------------------------------------------
     
     
     
    def Grille(fen,x,y, taille_case, taille_case_ap):
        def onClick(event):
     
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            tag = canvas.itemcget(monitem, "tag").split()[0]
            monitem_ap = canvas_ap.find_withtag(tag)[0]
     
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
                canvas_ap.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
                canvas_ap.itemconfigure(monitem, fill='white')
     
        "Dessine la grille"
     
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
     
     
        for i in range(x):
            for j in range(y):
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white', tag="%i*%i"%(i, j))
     
     
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
    #-------------------------------------------------------------------------------
     
     
    def Apercu(fen,x,y,taille_case):
        "Dessine l'aperçu"
     
        global canvas_ap
        canvas_ap = Canvas(fen, width =x*taille_case, height=y*taille_case)
     
        for i in range(x):
            for j in range(y):
                canvas_ap.create_rectangle((i*taille_case),(j*taille_case),((i+1)*taille_case) , ((j+1)*taille_case), outline='white',fill='white', width=0, tag="%i*%i"%(i, j))
     
     
        canvas_ap.pack()
    #-------------------------------------------------------------------------------
    root = Tk()
    Apercu(root,25,25,5)
    Grille(root,25,25,20,5)
    root.mainloop()
    Il y a surement une méthode plus simple, je trouve tout ça un peu tordu. Il faudrait lire la doc attentivement.

  6. #6
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Puisque le code de l'aperçu et du canvas principal est le même les index sont les même.

    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
    #-*- coding: utf-8 -*-
    from Tkinter import *
    #-------------------------------------------------------------------------------
    def Grille(fen,x,y):
        def onClick(event):
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
                canvasapercu.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
                canvasapercu.itemconfigure(monitem, fill='white')
     
        "Les canvas"
        taille_apercu=5
        taille_case=20
        canvasapercu = Canvas(fen, width =x*taille_apercu+4, height=y*taille_apercu+4)
        canvas = Canvas(fen, width =x*taille_case+4, height=y*taille_case+4)
     
        i = 0
        while i < x:
            j = 0
            while j < y:
                canvasapercu.create_rectangle((i*taille_apercu)+2,(j*taille_apercu)+2,((i+1)*taille_apercu)+2 , ((j+1)*taille_apercu)+2, outline='white',fill='white')
                canvas.create_rectangle((i*taille_case)+2,(j*taille_case)+2,((i+1)*taille_case)+2 , ((j+1)*taille_case)+2, fill='white')
                j+=1
            i+=1
        canvasapercu.pack()
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
     
    root = Tk()
     
    Grille(root,25,25)
    root.mainloop()
    @+

  7. #7
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Et pour faire mumuse...
    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
     
    #-*- coding: utf-8 -*-
    #
    #
    #
    from Tkinter import *
    #-------------------------------------------------------------------------------
    class wicanvas(Canvas):
        def __init__(self, master, x, y, taille, couleurbd):
            Canvas.__init__(self, master, width =x*taille+4, height=y*taille+4)
            i = 0
            while i < x:
                j = 0
                while j < y:
                    self.create_rectangle((i*taille)+2,(j*taille)+2,((i+1)*taille)+2 , ((j+1)*taille)+2, outline=couleurbd, fill='white')
                    j+=1
                i+=1
     
    def Grille(fen,x,y):
        def onClick(event):
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
                canvasapercu.itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
                canvasapercu.itemconfigure(monitem, fill='white')
     
        canvasapercu = wicanvas(fen, x, y, 5, 'white')
        canvas = wicanvas(fen, x, y, 20, 'black')
        canvasapercu.pack()
        canvas.pack()
        canvas.bind('<ButtonRelease-1>', onClick)
     
    root = Tk()
    Grille(root, 25, 25)
    root.mainloop()

  8. #8
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Un dernier avant d'aller au taf

    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
    #-*- coding: utf-8 -*-
    #
    #
    #
    from Tkinter import *
    #-------------------------------------------------------------------------------
    class wicanvas(Canvas):
        def __init__(self, master, x, y, taille, couleurbd):
            Canvas.__init__(self, master, width =x*taille+4, height=y*taille+4)
            i = 0
            while i < x:
                j = 0
                while j < y:
                    self.create_rectangle((i*taille)+2,(j*taille)+2,((i+1)*taille)+2 , ((j+1)*taille)+2, outline=couleurbd, fill='white')
                    j+=1
                i+=1
     
    def Grille(fen,x,y):
        def onClick(event):
            monitem = canvas.find_closest(canvas.canvasx(event.x), canvas.canvasy(event.y))
            if canvas.itemcget(monitem, 'fill') == 'white':
                canvas.itemconfigure(monitem, fill='black')
                for i in range(0, 3):
                    canvasapercu[i].itemconfigure(monitem, fill='black')
            else:
                canvas.itemconfigure(monitem, fill='white')
                for i in range(0, 3):
                    canvasapercu[i].itemconfigure(monitem, fill='white')
     
        canvasapercu = {}
        conteneur = Frame(fen)
        for i in range(0, 3):
            canvasapercu[i] = wicanvas(conteneur, x, y, 5, 'white')
            canvasapercu[i].pack(side=LEFT, padx=10)
        conteneur.pack(side=TOP)
     
        canvas = wicanvas(fen, x, y, 20, 'black')
        canvas.pack(side=TOP)
        canvas.bind('<ButtonRelease-1>', onClick)
     
    root = Tk()
    Grille(root, 25, 25)
    root.mainloop()
    Avec l'introduction de la notion de tag par nyko77 je pense que tu as de quoi faire

    @+

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Par défaut
    Puisque le code de l'aperçu et du canvas principal est le même les index sont les même.
    A oui, bien vu. j'avais pas pas pensé que les id était les mêmes.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 3
    Par défaut
    Merci pour vos réponses nyko77 et Pausekawa, Merci beaucoup.

  11. #11
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Un petit Résolu ?

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

Discussions similaires

  1. HELP! Demande aide pour petit site à réaliser en ASP et JS
    Par itachi64 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 12/03/2006, 09h06
  2. Réponses: 2
    Dernier message: 11/03/2006, 19h34
  3. Besoin d'aide pour requête sur grosse table
    Par Fabouney dans le forum Langage SQL
    Réponses: 3
    Dernier message: 25/01/2006, 09h01
  4. demande aide pour XML/XSL
    Par Jarod51 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 11/01/2006, 19h10
  5. aide pour requete sur 2 tables avec clé étranere
    Par richton95 dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/12/2005, 13h32

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