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 :

Supprimer des lignes et des colonnes d'une grille


Sujet :

Tkinter Python

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut Supprimer des lignes et des colonnes d'une grille
    Bonjour, j'ai crée une grille qui contient des labels encapsulés dans des rectangles.
    Je voudrais que lorsque on clique sur un label, la colonne et la ligne qui le contienne soit supprimées.
    Je sais supprimer ces lignes et ces colonnes lorsque la grille contient uniquement des rectangles vides.

    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
    import tkinter as tk
     
    DIM_GRILLE = (8, 8)
    DIM_CASE = 50
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASE + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASE + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
     
    def destroyer(evt) :
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
     
        # Récupération des index ligne et colonne contenant l'id rectangle
        for il, ligne in enumerate(items) :
            if rid in ligne :
                ic = ligne.index(rid)
                break
     
        # Suppressions de la ligne et colonne du tableau items
        # Et suppression dans le canevas
        lid = items.pop(il)
        for oid in lid :
            can.delete(oid)
     
        for ligne in items :
            oid = ligne.pop(ic)
            can.delete(oid)
     
        if not any(items) :
            # Plus rien à faire, le tableau d'items est vide.
            return
     
        nombreLignes = len(items)
        nombreColonnes = len(items[0])
     
        # Calculs des dimensions de chaque lignes
        # Soustraction des lignes de la hauteur du canevas
        hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
        # Répartition de la hauteur
        hauteurs = [hautCan // nombreLignes] * nombreLignes
        for i in range(hautCan % nombreLignes) :
            hauteurs[i] += 1
     
        # Calculs des dimensions de chaque colonnes
        largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
        largeurs = [largCan // nombreColonnes] * nombreColonnes
        for i in range(largCan % nombreColonnes) :
            largeurs[i] += 1
     
        # Mises à jour des dimensions
        ih = 0
        y = DIM_LIGNE
        for ligne in items :
            il = 0
            x = DIM_LIGNE
            for oid in ligne :
                can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                x += largeurs[il] + DIM_LIGNE
                il += 1
            ih += 1
            try :
                y += hauteurs[ih] + DIM_LIGNE
            except IndexError :
                # Dernier tour de boucle
                break
     
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['red', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
            i = can.create_rectangle(
                x, y, x+DIM_CASE, y+DIM_CASE,
                fill=colors[col % 2],
                width=0,
                # tags='l{} c{}'.format(ligne, col),
            )
            ids.append(i)
            x += DIM_CASE + DIM_LIGNE
        items.append(ids)
        y += DIM_CASE + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()
    Pour l'instant je bloque avec les labels. Je suppose qu'il faut remplacer ids.append(i) par ids.append((i,text_item)) mais je rencontre ensuite un problème dans la fonction destroyer. Pourriez-vous m'aider à le résoudre, svp. Je vous en remercie d'avance.

    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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
     
    def destroyer(evt) :
     
        #print(F[2])
     
        print (can.itemcget(items[0], 'fill'))
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
     
        print(r)
     
        myColor = can.itemcget(rid,'fill')
        print(myColor)
     
        if myColor == "yellow":
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items[0]) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(ic)
                    break
     
            # Suppressions de la ligne et colonne du tableau items
            # Et suppression dans le canevas
            lid = items[0].pop(il)
            for oid in lid :
                can.delete(oid)
     
            for ligne in items[0] :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items est vide.
                return
     
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
     
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="C/L", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="YYYY", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="XXXX", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="TEXT", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids.append((i,text_item))
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Arsene12 Voir le message
    Pourriez-vous m'aider à le résoudre, svp. Je vous en remercie d'avance.
    Essayez d'énoncer le problème rencontré, bien sûr, histoire qu'on sache quoi regarder dans le code ou qu'on n'en soit pas réduit à lancer le script pour voir ce qui ne va pas, mais pas que: énoncer le problème est le début de la solution.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Quand j'exécute le script et que je clique sur un label jaune j'obtiens :

    oid = ligne.pop(ic)
    UnboundLocalError: local variable 'ic' referenced before assignment
    J'essaye d'utiliser items[0] car j'ai un tuple, mais ça marche pas.

    Si je mets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for ligne in items[0] :  # au lieu  de in items:
         oid = ligne.pop(ic)
    j'obtiens :

    oid = ligne.pop(ic)
    AttributeError: 'tuple' object has no attribute 'pop'

    Le problème se situe dans cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(il)
                    break
    Quand je n'ai pas de tuple (ids.append(i)), et que je clique sur un label jaune, print(il) me renvoie un chiffre.
    Mon problème est donc que je n'arrive pas à récupérer les index lignes et colonnes quand j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="TEXT", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids.append(i,text_item))

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    UnboundLocalError: local variable 'ic' referenced before assignment veut juste dire que rien n'a été assigné à 'ic' avant d'y accéder.
    Puis sans réfléchir à cette erreur vous bricolez "for ligne in items[0]" qui récupère un tuple (puisque vous avez fabriqué une liste de listes de tuple) et çà plante avant de rencontrer 'ici' avec: AttributeError: 'tuple' object has no attribute 'pop'.
    Normal, non?
    D'autre part, avant de coder, essayez de réfléchir un peu. Si on affiche un tableau de carrés/rectangles dont on connaît la dimension des côtés, à tout (x, y) on sait retrouver le numéro (i, j) de la case en en divisant x par la longueur d'un côté et y par celui de l'autre côté.... Et c'est bien plus rapide que de parcourir une liste de listes pour comparer les identifiants.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    UnboundLocalError: local variable 'ic' referenced before assignment veut juste dire que rien n'a été assigné à 'ic' avant d'y accéder.- W
    C'est bien ce que j'avais déduis dans mon précédent message. Je disais que lorsque j'avais un tuple (ids.append(i,text_item))), print(il) me renvoyait pas de chiffre donc il n'y avait pas d'ic = ligne.index(rid), et ic n'était pas référencé. En bref, la condition rid in ligne n'était pas remplie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(il)
                    break
    Citation Envoyé par wiztricks Voir le message
    D'autre part, avant de coder, essayez de réfléchir un peu. Si on affiche un tableau de carrés/rectangles dont on connaît la dimension des côtés, à tout (x, y) on sait retrouver le numéro (i, j) de la case en en divisant x par la longueur d'un côté et y par celui de l'autre côté.... Et c'est bien plus rapide que de parcourir une liste de listes pour comparer les identifiants.
    - W
    Cette méthode fonctionne bien lorsque je n'ai que des rectangles. Je la maîtrise pas encore entièrement. Je suis en train d'y réfléchir dessus.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Je disais que lorsque j'avais un tuple (ids.append(i,text_item))), print(il) me renvoyait pas de chiffre donc il n'y avait pas d'ic = ligne.index(rid), et ic n'était pas référencé. En bref, la condition rid in ligne n'était pas remplie.
    Ben oui: avec ligne, une liste de tuples, et rid, un entier: rid in ligne sera toujours faux. Si vous ne cherchez pas à comprendre ce que vous écrivez...
    Puis soyez attentif: .find_overlapping vous retourne plusieurs items/entiers, vous choisissez le premier de cette liste, pourquoi?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Ben oui: avec ligne, une liste de tuples, et rid, un entier: rid in ligne sera toujours faux. Si vous ne cherchez pas à comprendre ce que vous écrivez...
    Puis soyez attentif: .find_overlapping vous retourne plusieurs items/entiers, vous choisissez le premier de cette liste, pourquoi?
    - W
    C'est cette première partie de la fonction que je trouve très compliquée. Contractée, elle fait 15 lignes et je suis pas encore arrivé à la comprendre malgré de très bons commentaires que je reprends pas ci-dessous.

    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
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0] 
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    break
            lid = items.pop(il)
            for oid in lid :
                can.delete(oid)     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    C'est cette première partie de la fonction que je trouve très compliquée. Contractée, elle fait 15 lignes et je suis pas encore arrivé à la comprendre malgré de très bons commentaires que je reprends pas ci-dessous.
    Si ce code fonctionne, c'est pour des listes de listes d'entiers par pour des listes de tuples et pas pour un .find_overlapping retournant plusieurs identifiants.

    Et si vous ne comprenez pas ce code, c'est que listes, boucles,... sont encore plein de mystères pour vous. Pourtant, ce sont des constructions de base du langage, si vous n'êtes pas à l'aise avec, programmer avec tkinter devient prise de chou car on se retrouve vite avec des tas de collections d'objets et donc listes, dictionnaires, boucles...
    A vous de prendre le temps d'ouvrir un tuto. et d'apprendre à maîtriser les bases avant de vous lancer dans des projets plus ambitieux.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Je pense que si j'arrive à comprendre ce code, j'aurai fait de très gros progrès. J'ai fait une modif en laissant tombé le rectangle pour ne m'occuper que du champs de texte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="TEXT", fill="white")
            ids.append(text_item)
    Le code fonctionne pour la suppression des lignes et des colonnes mais y'a un bug pour le reformatage :
    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
    self.tk.call((self._w, 'coords') + args))]
    _tkinter.TclError: wrong # coordinates: expected 0 or 2, got 4
    J'avais pensé créer 2 items, items1[] et items2[] pour éviter les tuples.


    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
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    ) 
     
    def destroyer(evt) :
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
        print(r)
        myColor = can.itemcget(rid,'fill')
        print(myColor)
     
        if myColor == "white":       
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(il)
                    break
     
            # Suppressions de la ligne et colonne du tableau items
            # Et suppression dans le canevas
            lid = items.pop(il)
            for oid in lid :
                can.delete(oid)
     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items est vide.
                return
     
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
     
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
            text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="TEXT", fill="white")
            ids.append(text_item)
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Arsene12 Voir le message
    Le code fonctionne pour la suppression des lignes et des colonnes mais y'a un bug pour le reformatage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
    self.tk.call((self._w, 'coords') + args))]
    _tkinter.TclError: wrong # coordinates: expected 0 or 2, got 4
    Ce n'est pas un bug, vous écrivez des instructions sans les comprendre.
    La méthode .coords attends le nombre de coordonnées d'un item "text". Il n'en a que 2 puisque vous l'avez créé en ne donnant que la position x, y (coin haut à gauche) et vous lui en passez 4.
    Je sais que c'est difficile mais si vous n'êtes pas assez à l'aise pour ouvrir la documentation du Canvas et comprendre ce qui y est écrit, c'est que ce que vous essayez de faire est encore trop difficile pour vous. C'est comme çà et on est tous passés par là.

    Citation Envoyé par Arsene12 Voir le message
    Je pense que si j'arrive à comprendre ce code, j'aurai fait de très gros progrès.
    Il vous manque les bases, un peu d'expérience et surtout la patience de les acquérir... Même si vous pensez avoir compris quelque chose, apprendre, c'est bien plus compliqué.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci de m'avoir indiqué d'où venait l'erreur. J'ai rectifié et maintenant ça marche bien. J'ai maintenant 2 codes qui fonctionnent à peu près bien : celui où y'a une grille constituée de rectangles sans texte,

    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
    import tkinter as tk
     
    DIM_GRILLE = (8, 8)
    DIM_CASE = 50
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASE + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASE + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
     
    def destroyer(evt) :
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
     
        # Récupération des index ligne et colonne contenant l'id rectangle
        for il, ligne in enumerate(items) :
            if rid in ligne :
                ic = ligne.index(rid)
                break
     
        # Suppressions de la ligne et colonne du tableau items
        # Et suppression dans le canevas
        lid = items.pop(il)
        for oid in lid :
            can.delete(oid)
     
        for ligne in items :
            oid = ligne.pop(ic)
            can.delete(oid)
     
        if not any(items) :
            # Plus rien à faire, le tableau d'items est vide.
            return
     
        nombreLignes = len(items)
        nombreColonnes = len(items[0])
     
        # Calculs des dimensions de chaque lignes
        # Soustraction des lignes de la hauteur du canevas
        hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
        # Répartition de la hauteur
        hauteurs = [hautCan // nombreLignes] * nombreLignes
        for i in range(hautCan % nombreLignes) :
            hauteurs[i] += 1
     
        # Calculs des dimensions de chaque colonnes
        largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
        largeurs = [largCan // nombreColonnes] * nombreColonnes
        for i in range(largCan % nombreColonnes) :
            largeurs[i] += 1
     
        # Mises à jour des dimensions
        ih = 0
        y = DIM_LIGNE
        for ligne in items :
            il = 0
            x = DIM_LIGNE
            for oid in ligne :
                can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                x += largeurs[il] + DIM_LIGNE
                il += 1
            ih += 1
            try :
                y += hauteurs[ih] + DIM_LIGNE
            except IndexError :
                # Dernier tour de boucle
                break
     
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['red', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
            i = can.create_rectangle(
                x, y, x+DIM_CASE, y+DIM_CASE,
                fill=colors[col % 2],
                width=0,
                # tags='l{} c{}'.format(ligne, col),
            )
            ids.append(i)
            x += DIM_CASE + DIM_LIGNE
        items.append(ids)
        y += DIM_CASE + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()
    et celui où y'a une grille remplie de champs de texte.

    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
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    ) 
     
    def destroyer(evt) :
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
        print(r)
        myColor = can.itemcget(rid,'fill')
        print(myColor)
     
        if myColor == "white":       
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(il)
                    break
     
            # Suppressions de la ligne et colonne du tableau items
            # Et suppression dans le canevas
            lid = items.pop(il)
            for oid in lid :
                can.delete(oid)
     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items est vide.
                return
     
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
     
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x+largeurs[il]/2, y+hauteurs[ih]/2)
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
            text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="TEXT", fill="white")
            ids.append(text_item)
            print(text_item)
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()
    Il me faudrait fusionner les 2.

    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
    134
    135
    136
    137
    138
    139
    140
    141
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    ) 
     
    def destroyer(evt) :
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
        print(r)
        myColor = can.itemcget(rid,'fill')
        print(myColor)
     
        if myColor == "yellow":       
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items1) :
                if rid in ligne :
                    ic = ligne.index(rid)
                    print(il)
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items1.pop(il)
            for oid in lid :
                can.delete(oid)
     
            for ligne in items1 :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items1) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
            nombreLignes = len(items1)
            nombreColonnes = len(items1[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
     
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items1 :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items1 = []
    items2 = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids1 = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="white")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids1.append(i)
            ids2.append(text_item)
            print(i)
            x += DIM_CASEL + DIM_LIGNE
        items1.append(ids1)
        items2.append(ids2)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()
    Je me dis que c'est en forgeant qu'on devient forgeron et qu'apprendre consiste à faire le va-et-vient entre les exemples et les tutos. Donc je garde espoir de réaliser ce code et de bien le comprendre.

    Je me questionne sur l'utilité de la bbox. Je pourrais peut-être remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="white")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            text_item = can.create_text(x+DIM_CASE/2, y+DIM_CASE/2, text="VRAI", fill="black")
            i = can.create_rectangle(
                x, y, x+DIM_CASE, y+DIM_CASE,
                fill=colors[col % 2],
                width=0,
                # tags='l{} c{}'.format(ligne, col),
            )

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Je me dis que c'est en forgeant qu'on devient forgeron et qu'apprendre consiste à faire le va-et-vient entre les exemples et les tutos. Donc je garde espoir de réaliser ce code et de bien le comprendre.
    Ah ben, si vous pensez qu'on peut construire une maison sans commencer par les fondations... apprendre, est aussi un processus d'accumulation où il faut commencer par maîtriser les constructions simples pour les retrouver dans les assemblages plus compliqués sinon, çà restera illisible/incompréhensible (ou pire, on croit comprendre, et on se retrouve perdu dès qu'on change un détail).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Si nous étudions le problème sous l'angle des coordonnées, le but de la fonction est d'éliminer tous les rectangles dont les coins supérieurs gauches partagent au moins une des coordonnées avec le coin supérieur gauche du rectangle sur lequel on clique.

    Y'a un point que j'aimerais qu'on m'éclaircisse. Quand on clique sur le canvas, on récupére les coordonnées du clic de la souris par evt.x et evt.y. On s'en sert quand on écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
    La définition de find_overlapping nous dit :
    Canvas.find_overlapping(x1,y1,x2,y2)
    Retourne la liste des identifiants numériques des items qui ont au moins un point commun avec le rectangle x1,y1,x2,y2.
    Pour moi l'idée était de récupérer les coordonnées x1 et y1 du rectangle sur lequel on clique pour pouvoir éliminer ensuite tous les rectangles qui ont x1 ou y1 en commun. Je suis un peu perdu avec les identifiants.

    Quand je clique au hasard dans le canvas, le print(r) du code ci-dessous me renvoie :
    -soit un tuple (nbre1,nbre2): une liste de 2 éléments qui correspondent à 2 identifiants,
    -soit un seul nombre (nbre,).
    -soit une liste vide ()

    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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
     
    def destroyer(evt) :
     
        #print("SELECT = "+str(can.select_item()))
        #print(can.find_all())
        #print("CLOSEST = "+str(can.find_closest(evt.x, evt.y, evt.x, evt.y)))
        #print("CLOSEST X = "+str(can.find_closest(evt.x, evt.y)))    
        #print("ENCLOSED X = "+str(can.find_enclosed(evt.x, evt.y, evt.x, evt.y)))
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        print("R= "+str(r))
        if not r :
            return
        rid = r[0]
        #print("RID = "+str(rid))
        #print("R = "+str(r))
        myColor = can.itemcget(rid,'fill')
        #print(myColor)
     
        if myColor == "yellow":       
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items1) :
                #print("IL = "+str(il))
                if rid in ligne :
                    ic = ligne.index(rid)
                    #print("IC = "+str(ic))
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items1.pop(il)
            for oid in lid :
                can.delete(oid)
     
            for ligne in items1 :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items1) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
            nombreLignes = len(items1)
            nombreColonnes = len(items1[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
     
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items1 :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            #print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items1 = []
    #items2 = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids1 = []
        #ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="VRAI", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids1.append(i)
            #ids2.append(text_item)
            #print(i)
            x += DIM_CASEL + DIM_LIGNE
        items1.append(ids1)
        #items2.append(ids2)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Arsene12 Voir le message
    Quand je clique au hasard dans le canvas, le print(r) du code ci-dessous me renvoie :
    -soit un tuple (nbre1,nbre2): une liste de 2 éléments qui correspondent à 2 identifiants,
    -soit un seul nombre (nbre,).
    -soit une liste vide ()
    Ce sont les identifiants des items à cet endroit. C'est cohérent avec ce que vous avez créé. Vous pouvez récupérer le type de chaque item via canvas.type(TagOrId).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Vous pouvez récupérer le type de chaque item via canvas.type(TagOrId).- W
    Merci. J'ai mis dans mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        print("R= "+str(r))
     
        print(can.type(r[0]))
        print(can.type(r[1]))
    et ça me réponds :

    R= (800, 799)
    rectangle
    text
    R= (710, 709)
    rectangle
    text
    Il me faut maintenant vérifier si la réponse obtenue est bien un tuple et à partir de là, exécuter un traitement adéquat.

  16. #16
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Bonjour,

    j'ai trouvé comment supprimer les colonnes et les lignes qui contiennent des rectangles avec des labels à l'intérieur. J'ai crée 2 listes : une pour les rectangle et une autre pour les labels. Et j'ai éliminer les rectangles et les labels les uns après les autres. Je sais ensuite redéfinir la dimension des lignes et des colonnes afin qu'elles occupent tout l'espace de la fenêtre principale. Par contre j'ai un problème pour repositionner les champs de texte au centre de leurs rectangles respectifs.

    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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
    def destroyer(evt) :
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        rid = r[0]
        rid2 = r[1]
        #print("RID = "+str(rid))
        #print("R = "+str(r))
        myColor = can.itemcget(rid,'fill')
        myText = can.itemcget(rid2,'text')
     
        if myText == "VRAI" and myColor == "yellow":
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                if rid in ligne:
                    ic = ligne.index(rid)
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items.pop(il)
            for oid in lid:
                can.delete(oid)
     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items2) :
                print("IL = "+str(il))
                if rid2 in ligne:
                    ic2 = ligne.index(rid2)
                    print("IC2 = "+str(ic2))
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items2.pop(il)
            for oid2 in lid:
                can.delete(oid2)
     
            for ligne in items2 :
                oid2 = ligne.pop(ic2)
                can.delete(oid2)
     
            if not any(items2) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
     
     
            '''
            
         
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
         
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
         
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
         
            # Mises à jour des dimensions
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
            '''
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            #print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    items2 = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids1 = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="VRAI", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids1.append(i)
            ids2.append(text_item)
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids1)
        items2.append(ids2)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    J'y suis enfin arrivé. Ça marche pour ce qui est du recentrage. Mais quand je clique au hasard dans le canvas, ça me répond parfois :

    rid2 = r[1]
    IndexError: tuple index out of range


    Un fois ce dernier problème réglé, mon but sera atteint.


    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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 30
    DIM_CASEH = 20
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
    def destroyer2(evt) :
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        print("R= "+str(r))
     
        print(can.type(r[0]))
        print(can.type(r[1]))
     
     
     
    def destroyer(evt) :
     
        #print("SELECT = "+str(can.select_item()))
        #print(can.find_all())
        #print("CLOSEST = "+str(can.find_closest(evt.x, evt.y, evt.x, evt.y)))
     
        #print("CLOSEST X = "+str(can.find_closest(evt.x, evt.y)))
     
        #print("ENCLOSED X = "+str(can.find_enclosed(evt.x, evt.y, evt.x, evt.y)))
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        print("R= "+str(r))
        if not r :
            return
        rid = r[0]
        rid2 = r[1]
        #print("RID = "+str(rid))
        #print("R = "+str(r))
        myColor = can.itemcget(rid,'fill')
        myText = can.itemcget(rid2,'text')
        #print(myColor)
        print(myText)
     
        #if myColor == "yellow":
        if type(r) is tuple and myText == "VRAI" and myColor == "yellow":
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                #print("IL = "+str(il))
                if rid in ligne:
                    ic = ligne.index(rid)
                    #print("IC2 = "+str(ic2))
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items.pop(il)
            for oid in lid:
                can.delete(oid)
     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
            ''
     
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items2) :
                print("IL = "+str(il))
                if rid2 in ligne:
                    ic = ligne.index(rid2)
                    print("IC2 = "+str(ic))
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items2.pop(il)
            for oid in lid:
                can.delete(oid)
     
            for ligne in items2 :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items2) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
     
     
            ''
     
     
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
            ''
            # Mises à jour des dimensions RECTANGLE
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
     
            ''
            # Mises à jour des dimensions TEXTE
            ih = 0
            y = DIM_LIGNE
            for ligne in items2 :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x+largeurs[il]/2, y+hauteurs[ih]/2)
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
            ''
     
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            #print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    items2 = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids1 = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="VRAI", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids1.append(i)
            ids2.append(text_item)
            #print(i)
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids1)
        items2.append(ids2)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    J'y suis enfin arrivé. Ça marche pour ce qui est du recentrage. Mais quand je clique au hasard dans le canvas, ça me répond parfois :

    rid2 = r[1]
    IndexError: tuple index out of range
    A quoi sert de tester et constater que çà retourne 0, 1, 2 items pour, in fine, écrire un code qui n'en tienne pas compte?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    A quoi sert de tester et constater que çà retourne 0, 1, 2 items pour, in fine, écrire un code qui n'en tienne pas compte?
    - W
    J'ai rectifié le code. Ça marche, j'ai plus le problème du out of range. Par contre, lorsque je clique dans le rectangle mais pas sur le texte, je n'obtiens pas un tuple à 2 nombres. Donc le clic ne donne rien. Je pense que je vais devoir changer le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
    .

    Ça rejoint ce que je disais en dernier dans ce topic.

    Je pensais pouvoir le remplacer par r = can.find_enclosed(evt.x, evt.y, evt.x, evt.y). Mais ça donne la même chose.

    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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    import tkinter as tk
     
    DIM_GRILLE = (20, 20)
    DIM_CASEL = 60
    DIM_CASEH = 30
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASEL + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASEH + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
    def destroyer2(evt) :
        #r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        r = can.find_enclosed(evt.x, evt.y, evt.x, evt.y)
        print("R= "+str(r))
     
        print(can.type(r[0]))
        print(can.type(r[1]))    
     
    def destroyer(evt) :
     
        #print("SELECT = "+str(can.select_item()))
        #print(can.find_all())
        #print("CLOSEST = "+str(can.find_closest(evt.x, evt.y, evt.x, evt.y)))
     
        #print("CLOSEST X = "+str(can.find_closest(evt.x, evt.y)))
     
        #print("ENCLOSED X = "+str(can.find_enclosed(evt.x, evt.y, evt.x, evt.y)))
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        #print("R= "+str(r))
        myTupL = len(r)
        print("LONGUEUR = "+str(myTupL))
     
        if myTupL == 2 :       
            rid = r[0]
            rid2 = r[1]        
            print("RID = "+str(rid))
            print("RID2 = "+str(rid2))
            #print("R = "+str(r))
            myColor = can.itemcget(rid,'fill')
            myText = can.itemcget(rid2,'text')
        else:
            print("FALSE")
            return
        print(myColor)
        #print(rid2)
     
        if not rid :
            print("ARRETEZ TOUT")
     
        if not rid2 >1 :
            print("STOP1 = "+ str(rid2))
            #return   
     
        #if myColor == "yellow":
        elif myTupL==2 and (myText == "VRAI" or myColor == "yellow"):        
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items) :
                #print("IL = "+str(il))
                if rid in ligne:
                    ic = ligne.index(rid)
                    #print("IC2 = "+str(ic2))
                    break
            #print("IC2 = "+str(ic))
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items.pop(il)
            for oid in lid:
                can.delete(oid)
     
            for ligne in items :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return
     
            ''
     
            # Récupération des index ligne et colonne contenant l'id rectangle
            for il, ligne in enumerate(items2) :
                #print("IL = "+str(il))
                if rid2 in ligne:
                    ic = ligne.index(rid2)                
                    break
     
            # Suppressions de la ligne et colonne du tableau items1
            # Et suppression dans le canevas
            lid = items2.pop(il)
            for oid in lid:
                can.delete(oid)
     
            for ligne in items2 :
                oid = ligne.pop(ic)
                can.delete(oid)
     
            if not any(items2) :
                # Plus rien à faire, le tableau d'items1 est vide.
                return        
     
            ''        
     
            nombreLignes = len(items)
            nombreColonnes = len(items[0])
     
            # Calculs des dimensions de chaque lignes
            # Soustraction des lignes de la hauteur du canevas
            hautCan = DIM_CANEVAS[1] - (nombreLignes+1) * DIM_LIGNE
            # Répartition de la hauteur
            hauteurs = [hautCan // nombreLignes] * nombreLignes
            for i in range(hautCan % nombreLignes) :
                hauteurs[i] += 1
     
            # Calculs des dimensions de chaque colonnes
            largCan = DIM_CANEVAS[0] - (nombreColonnes+1) * DIM_LIGNE
            largeurs = [largCan // nombreColonnes] * nombreColonnes
            for i in range(largCan % nombreColonnes) :
                largeurs[i] += 1
            ''
            # Mises à jour des dimensions RECTANGLE
            ih = 0
            y = DIM_LIGNE
            for ligne in items :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x, y, x+largeurs[il], y+hauteurs[ih])
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break        
            ''
            # Mises à jour des dimensions TEXTE
            ih = 0
            y = DIM_LIGNE
            for ligne in items2 :
                il = 0
                x = DIM_LIGNE
                for oid in ligne :
                    can.coords(oid, x+largeurs[il]/2, y+hauteurs[ih]/2)
                    x += largeurs[il] + DIM_LIGNE
                    il += 1
                ih += 1
                try :
                    y += hauteurs[ih] + DIM_LIGNE
                except IndexError :
                    # Dernier tour de boucle
                    break
            ''        
     
            j=evt.x#//DIM_CASEL)
            i=evt.y#//DIM_CASEL)
            #print('Les coordonnées du carreau cliqué sont ('+str(i)+','+str(j)+')')
        else:
            pass
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    items2 = []
    colors = ['white', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids1 = []
        ids2 = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
     
            #text_item = can.create_text(x+DIM_CASEL, y+DIM_CASEL, text="VRAI", fill="white")
     
            if ligne == 0 and col==0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif ligne == 0 and col>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            elif col == 0 and ligne>0:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="         ", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="black", fill="red")
                can.tag_raise(text_item,i)
            else:
                text_item = can.create_text(x+DIM_CASEL/2, y+DIM_CASEH/2, text="VRAI", fill="black")
                bbox = can.bbox(text_item)
                i = can.create_rectangle(bbox, outline="red", fill=colors[col % 2])
                can.tag_raise(text_item,i)
            ids1.append(i)
            ids2.append(text_item)
            #print(i)
            x += DIM_CASEL + DIM_LIGNE
        items.append(ids1)
        items2.append(ids2)
        y += DIM_CASEH + DIM_LIGNE
     
    can.bind('<Button-1>', destroyer)
     
    fenetre.mainloop()

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Par contre, lorsque je clique dans le rectangle mais pas sur le texte, je n'obtiens pas un tuple à 2 nombres. Donc le clic ne donne rien.
    Le clic ne donne que la position x, y où l'utilisateur a cliqué.
    S'il clique sur un rectangle .find_overlapping retournera l'identifiant du dit rectangle: ce n'est pas rien. Le rectangle contient (éventuellement) un item "text". Et si c'est le cas, il sera dans la .bbox définie par le rectangle...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/11/2015, 12h25
  2. [Débutant] Supprimer des lignes et des colonnes d'une matrice
    Par hakimetudiant dans le forum MATLAB
    Réponses: 6
    Dernier message: 01/06/2015, 15h24
  3. Supprimer les lignes et les colonnes d'une image
    Par af.zakaria dans le forum OpenCV
    Réponses: 10
    Dernier message: 22/10/2013, 13h55
  4. Réponses: 8
    Dernier message: 29/04/2008, 13h58
  5. Traitement des lignes [suppression des lignes vides]
    Par turbo_chess dans le forum Linux
    Réponses: 4
    Dernier message: 22/03/2007, 09h16

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