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 :

Tk : Comment recharger fenêtre pour MaJ canvas -grille de jeu (Othello amateur) [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre régulier
    Homme Profil pro
    Amateur débutant
    Inscrit en
    Décembre 2019
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Amateur débutant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 88
    Points : 104
    Points
    104
    Par défaut Tk : Comment recharger fenêtre pour MaJ canvas -grille de jeu (Othello amateur)
    Bonjour,

    Je me suis risqué, pour apprentissage autodidacte, à un Othello avec Tkinter.
    j'ai pu bricoler un truc jouable avec une grille par défaut de 8x8.

    J'aimerai bien pouvoir paramétrer des grilles de jeu de tailles variables.
    j'ai donc ajouté on onglet paramètres où l'on sélectionne une autre taille de grille.

    Mais quand je change ce paramètre (i.e. sur 12 (pour 12x12 cases)) et que je clique sur [Nouvelle partie], j'observe deux problèmes:
    -C'est toujours la grille 8x8 qui se recharge (dans l'onglet grille) et,
    -Cette nouvelle grille ne fonctionne plus (plus de click détecté etc.).

    j'imagine qu'il faudrait que toute la fenêtre puisse être rechargée avec la nouvelle valeur 12 ou ..?
    Mais je tourne en rond, sans que la fonction reload(), appelée par le bouton [nouvelle partie] , n'agissent comme il le faudrait.

    Q: Auriez-vous, s'il vous plait, une idée (voire un bout de code) qui puisse débloquer cette situation?

    Voici le code (long désolé mais c'est pour que vous puissiez reproduire le comportement).
    (NB: Pour raccourcir ce code pour ce forum, la fonction checking() a été réduite au simple retournement des pions situés au dessus)
    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
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
     
    from tkinter import *
    from tkinter import ttk # si on fait pas cet import ca marche pas..pourquoi?
    from copy import deepcopy
     
     
    # création de la grille de jeu
    def create_board():
        global listPos
        decalLig=-cellSize
        for i in range(nbCase):
            decalLig+=cellSize
            decalCol=0
            listTemp=[]
            for j in range(nbCase):
                x1, y1 = 3+decalCol, 3+decalLig
                x2, y2 = x1+cellSize, y1+cellSize
                case = can.create_rectangle(x1, y1, x2, y2, fill='green',
                                                width="2", tag="Case")
                decalCol+=cellSize
                # ajouter les id de cases dans une matrice (liste de listes).
                listTemp.append(case)
            listPos.append(listTemp)
     
     
    # on place les 4 pions centraux en s'appuyant sur la coord du centre de la
    # grille qui est invariable (car la taille du canevas est invariable)
    def starting_pawns():
        global listPos
        pionHG = can.create_oval(244-(cellSize*11/12), 244-(cellSize*11/12), 244-(cellSize*1/12), 244-(cellSize*1/12), fill='white', width="2", tag="Blanc")
        pionHD = can.create_oval(244+(cellSize*1/12), 244-(cellSize*11/12), 244+(cellSize*11/12), 244-(cellSize*1/12), fill='black', width="2", tag="Noir")
        pionBG = can.create_oval(244-(cellSize*11/12), 244+(cellSize*1/12), 244-(cellSize*1/12), 244+(cellSize*11/12), fill='black', width="2", tag="Noir")
        pionBD = can.create_oval(244+(cellSize*1/12), 244+(cellSize*1/12), 244+(cellSize*11/12), 244+(cellSize*11/12), fill='white', width="2", tag="Blanc")
        listPos[int(nbCase/2-1)][int(nbCase/2-1)],listPos[int(nbCase/2-1)][int(nbCase/2)],listPos[int(nbCase/2)][int(nbCase/2-1)],listPos[int(nbCase/2)][int(nbCase/2)] = "B", "N", "N", "B"
     
     
    # repérage de la case cliquée et du tour
    def click_case(event):
        # event.x et event.y contiennent les coordonnées du clic effectué
        x1, y1 = event.x, event.y
     
        # <find_closest> renvoie la référence du dessin le plus proche
        selObject = can.find_closest(x1, y1)
        a1, b1, a2, b2 = can.coords(selObject)
     
        # detection si il n'y a pas déja un jeton dessiné sur la case
        if selObject[0] in can.find_withtag("Case"):
            # relever a quelle adresse de matrice correspond cette case
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if cpt==selObject[0]:
                        if turnBlanc==True:
                            s="B"
                        else:
                            s="N"
                        checking(i,j,s, selObject, a1, b1, a2, b2 )
     
     
    # trouver les pions à retourner autour de la case cliquée
    def checking(coordi, coordj, symbol, selCase, casX1, casY1, casX2, casY2):
        global listPos
    # vérif colone vers le haut-------------------------------------------------
        # on double les coordonnées reçues
        matY=coordi
        matX=coordj
     
        # on "clone" la matrice pour pouvoir y faire les modifs
        # que l'on appliquera à la matrice listPos en fin de procédure
        toBeFlipped=deepcopy(listPos)
     
        # on "clone" à nouveau cette matrice pour la comparer en fin de procédure
        toBeCompared=deepcopy(listPos)
     
        # création d'un indicateur pour appliquer ou non les changements
        flipHem=False
     
        while matY>0:
            matY-=1
            if (listPos[matY][matX]=="B" or listPos[matY][matX]=="N") and listPos[matY][matX]!= symbol:
                toBeFlipped[matY][matX]=symbol
            elif listPos[matY][matX]==symbol:
                flipHem=True
                break
            else:
                toBeFlipped=listPos
                break
        if flipHem==True:
            listPos=toBeFlipped
        else:
            toBeFlipped=listPos
     
        if toBeCompared != listPos:
            put_the_pawns(selCase, casX1, casY1, casX2, casY2)
            print(toBeCompared,"\n",listPos)
        else:
            prompt.config(text="case inactive")
     
     
    # on dessine le pion sur la case, on update la matrice avec ce nouveau pion puis
    # on change la couleur de tous les pions
    def put_the_pawns(clickedCase, x1, y1, x2, y2):
        global listPos
        # effacer le prompt (au cas ou il a été activé avant ce coup)
        prompt.config(text="")
        # si c'est au tour blanc
        if turnBlanc == True:
            # creation du jeton blanc
            can.create_oval(x1+(cellSize*1/12), y1+(cellSize*1/12),
                                        x2-(cellSize*1/12), y2-(cellSize*1/12),
                                        fill="white", width="2", tag="Blanc")
            # puis on positionne un B dans la matrice à l'endroit du clic
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if cpt==clickedCase[0]:
                        listPos[i][j]="B"
            # on recherche toutes les lettres B de la matrice
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if listPos[i][j] == "B":
                        a,b,c,d = can.coords(cpt)
                        jeton = can.find_enclosed(a,b,c,d)
                        can.itemconfigure(jeton[0], fill="white")
            calc_score()
     
        elif turnNoir == True:
            can.create_oval(x1+(cellSize*1/12), y1+(cellSize*1/12),
                                        x2-(cellSize*1/12), y2-(cellSize*1/12),
                                        fill="black", width="2", tag="Noir")
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if cpt==clickedCase[0]:
                        listPos[i][j]="N"
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if listPos[i][j] == "N":
                        a,b,c,d=can.coords(cpt)
                        jeton = can.find_enclosed(a,b,c,d)
                        can.itemconfigure(jeton[0], fill="black")
            calc_score()
     
     
    # calcul des scores
    def calc_score():
        global scoreB, scoreN
     
        scoreB=0
        for i in listPos:
            for j in i:
                if j=="B":
                    scoreB+=1
        scoreN=0
        for i in listPos:
            for j in i:
                if j=="N":
                    scoreN+=1
     
        change_player(scoreB, scoreN)
     
    # changement de joueur et modif des labels et scores
    def change_player(pointsB, pointsN):
        global turnBlanc, turnNoir, color4Blanc, color4Noir, scoreBLab, scoreNlab
     
        scoreBLab.config(text="Point Blanc :"+str(pointsB))
        scoreNLab.config(text="Point Noir :"+str(pointsN))
     
        if turnBlanc == True:
     
            # changement des fonds des labels
            color4Blanc = "light gray"
            color4Noir = "gray"
            scoreBLab.config(bg=color4Blanc)
            scoreNLab.config(bg=color4Noir)
     
            # changement de joueur
            turnBlanc = False
            turnNoir = True
     
        elif turnNoir == True:
     
            # changement des fonds des labels
            color4Blanc = "white"
            color4Noir =  "light gray"
            scoreBLab.config(bg=color4Blanc)
            scoreNLab.config(bg=color4Noir)
     
            # changement de joueur
            turnBlanc = True
            turnNoir = False
     
    def reload_game():
        global nbCase
        """fonction pour recharger le canvas avec la nouvelle variable
        nbCase mais ca fonctionne pas (reste en 8 cases et click ne fonctionne plus
        non plus) et j'arrive pas à trouver pourquoi"""
        # effacer le canvas
        can.delete('all')
        # recupérer la nouvelle valeur de nombre case"
        nbCase = int(comboCase.get())
        # metre le prompt a jour (montre qu'on est bien entré dans cette fonction)
        prompt.config(text="avec "+str(nbCase))
        # appels des fonctions pour créer la nouvelle grille
        create_board()
        starting_pawns()
     
     
    #-------------------------Programme principal----------------------------------#
     
    # creation de la fenetre tkinter
    fen = Tk()
    fen.title("Oh! t'es Low'")
    fen.config (bg = "light gray")
     
    # initialisations
    scoreB = 0
    scoreN = 0
    listPos=[]
    turnBlanc = True
    turnNoir = False
    color4Blanc = "white"
    color4Noir = "light gray"
     
    # label score et prompt
    scoreBLab = Label(fen, text="Point Blanc :"+str(scoreB), bg=color4Blanc)
    prompt = Label(fen, text="", bg="light gray")
    scoreNLab = Label(fen, text="Point Noir :"+str(scoreN), bg=color4Noir)
    scoreBLab.grid(row=0, column=0)
    prompt.grid(row=0, column=1)
    scoreNLab.grid(row=0, column=2)
     
    # creation du systeme d'onglets
    setOnglets = ttk.Notebook(fen)
    setOnglets.grid(row=1, columnspan=3)
     
    # ajout des l'onglets
    onglet1 = ttk.Frame(setOnglets)
    onglet1.pack()
    onglet2 = ttk.Frame(setOnglets)
    onglet2.pack()
    onglet3 = ttk.Frame(setOnglets)
    onglet3.pack()
     
    # nom des onglets
    setOnglets.add(onglet1, text='Grille de jeu')
    setOnglets.add(onglet2, text='Paramètres')
    setOnglets.add(onglet3, text='Règles')
     
    # creation du canevas dans l'onglet1
    canH = 483
    canW = 483
    can = Canvas(onglet1, height=canH, width=canW, bg="ivory")
    can.pack()
    # liaison d'événements <souris> au widget <canevas> :
    can.bind("<Button-1>", click_case)
     
    # labelFrame de l'onglet2
    labFram1 = LabelFrame(onglet2, text="nombre de case")
    labFram1.pack(fill="both", expand="No", padx=10)
    # placer le combox dans ce container
    comboCase = ttk.Combobox(labFram1,
                                values=["6",
                                        "8",
                                        "10",
                                        "12",
                                        "14",
                                        "16",
                                        "18",
                                        "20"])
    comboCase.current(1) # choix [1] (i.e. "8") dans la liste
    comboCase.pack(side=LEFT, pady=20 )
     
    # definition du nombre de cases par ligne de la grille
    nbCase = int(comboCase.get())
     
    # on définit la taille des cases en fonction de la taille du canevas (moins 3
    # pour voir les bordures) divisée par le nombre de cases
    cellSize = (canH-3)/nbCase
     
    #☺ création des bouton en bas de fenetre
    btnQuit = Button(fen, text='Quitter', command=fen.destroy)
    btnQuit.grid(row=2, column=0)
    btnReload = Button(fen, text='Nouvelle partie', command=reload_game)
    btnReload.grid(row=2, column=2)
     
    # creation de la grille via fonctions
    create_board()
    starting_pawns()
     
    # boucler la fenetre tkinter
    fen.mainloop()
    D'avance merci pour toute aide.
    Prenez soin de vous.

    Jean-Marie A.

  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 Jma06 Voir le message
    Mais quand je change ce paramètre (i.e. sur 12 (pour 12x12 cases)) et que je clique sur [Nouvelle partie], j'observe deux problèmes:
    -C'est toujours la grille 8x8 qui se recharge (dans l'onglet grille) et,
    -Cette nouvelle grille ne fonctionne plus (plus de click détecté etc.).
    Si votre canvas est de dimension NxN et que la taille des cellules est fixée par N divisé par le nombre de cellules initial, lorsque vous ajoutez des cellules, elles sortiront de la partie visible (sauf à "agrandir" le Canvas).

    "plus click détecté"... mouais ajoutez un print('click case') comme première instruction de la faonction qui gère les clicks...

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

  3. #3
    Membre régulier
    Homme Profil pro
    Amateur débutant
    Inscrit en
    Décembre 2019
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Amateur débutant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 88
    Points : 104
    Points
    104
    Par défaut
    Merci , en effet en ajoutant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        cellSize = (canH-3)/nbCase
    à la fonction reload_game() on voit bien toutes les cellules

    Citation Envoyé par wiztricks Voir le message
    "plus click détecté"... mouais ajoutez un print('click case') comme première instruction de la faonction qui gère les clicks...
    - W
    j'ai un <function click_case at 0x03E3E3D0>. vous vouliez me faire voir que cette fonction était bien appelée?
    mais pourquoi les jetons n'apparaissent-ils pas ensuite?
    Je veux dire, qu'est ce que je fais pas, qui permettrait aux fonctions de s’enchaîner et de fonctionner comme lors de l'ouverture du programme?

  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,

    Citation Envoyé par Jma06 Voir le message
    Je veux dire, qu'est ce que je fais pas, qui permettrait aux fonctions de s’enchaîner et de fonctionner comme lors de l'ouverture du programme?
    C'est parce que vous croyez que les identifiants des objets du Canvas sont réutilisés après un .delete('all'). Regardez ce que vous avez écrit dans click_case:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            cpt=0
            for i in range(nbCase):
                for j in range(nbCase):
                    cpt+=1
                    if cpt==selObject[0]:
    Un print(selObject) devrait vous convaincre que non...

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

  5. #5
    Membre régulier
    Homme Profil pro
    Amateur débutant
    Inscrit en
    Décembre 2019
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Amateur débutant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 88
    Points : 104
    Points
    104
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,
    C'est parce que vous croyez que les identifiants des objets du Canvas sont réutilisés après un .delete('all')...
    - W
    Merci wiztricks,
    Ai-je bien compris que
    -Les id, eux ne sont pas détruits par le can.delete('all')
    ->Quand une nouvelle grille est crée, de nouveaux id le sont aussi est s'ajoutent à la liste existante.
    ->Les opérations s'appuyant sur des id attendus comme démarrant à 1 sont fausses.
    ->Plus rien ne s'affiche/fonctionne.

    Faire can.destroy(), refaire un canvas (et sa liaison au clic de souris) semble fonctionner (au moment d'un rapide test et de cet écrit).
    Est-ce un méthode recevable selon vous? (ou existe t il une manière plus adéquate pour ce cas de figure?)

    En tous cas merci beaucoup, vous m'avez bien guidé et aidé.. as usual j'ai envie de dire.

  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
    Salut,

    Dire que les identifiants ne sont pas détruits est inexact: lorsqu'on crée un item, le Canvas lui associe un identifiant unique pour toute la durée de vie du Canvas. Si on supprime l'item son identifiant ne sera pas réutilisé.

    Faire can.destroy(), refaire un canvas (et sa liaison au clic de souris) semble fonctionner (au moment d'un rapide test et de cet écrit).
    Est-ce un méthode recevable selon vous? (ou existe t il une manière plus adéquate pour ce cas de figure?)
    Vous voyez bien (ou pas ) que votre soucis est dans l'association entre un clic en (x, y) et la case (i, j) correspondante. Et vous vous en êtes sorti avec votre bidouille de compteur utilisant l'identifiant de l'objet pour trouver le (i, j).

    Posez le problème différemment: vous connaissez la dimension de vos cases (cellSize) donc x // cellSize, y // cellSize va vous produire votre (i, j) (testez: il y a des ajustements à faire avec les "bords").

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

  7. #7
    Membre régulier
    Homme Profil pro
    Amateur débutant
    Inscrit en
    Décembre 2019
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Amateur débutant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 88
    Points : 104
    Points
    104
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,
    (ou pas )
    - W
    Si si je sentais bien en écrivant...
    que je devais bidouiller (pour faire avec tkinter un truc qui était plutôt bien en console).
    M'en suis sorti avec ce tricotage... sans prendre de hauteur pour voir le problème autrement comme vous l'avez fait.
    Je vais faire mon possible pour suivre votre conseil pour un prochain jeu de plateau avec Tkinter.
    Merci pour votre aide.
    Jma

  8. #8
    Membre régulier
    Homme Profil pro
    Amateur débutant
    Inscrit en
    Décembre 2019
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Amateur débutant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 88
    Points : 104
    Points
    104
    Par défaut
    j'ai un peu pensé à votre façon de poser le problème
    Est ce que vous pensiez à un truc un peu de ce style ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    i = floor(x/cellSize)
    j = floor(y/cellSize)

  9. #9
    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,

    Par exemple.
    Sauf que pour la division entière, pas besoin de floor, '//' suffit.

    - 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.

Discussions similaires

  1. [XL-2003] Comment faire rapidement pour que la fenêtre Propriétés soit solidaire de tout le bloc VBA
    Par Un Internaute dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 26/04/2015, 11h51
  2. [PHP-JS] Fenêtre invisible (pour MAJ BDD) ?
    Par Lideln dans le forum Langage
    Réponses: 7
    Dernier message: 01/08/2006, 19h05
  3. Réponses: 22
    Dernier message: 22/04/2005, 15h05
  4. [Debutant(e)]Quel composant utiliser pour faire une grille
    Par elitost dans le forum Composants
    Réponses: 7
    Dernier message: 21/06/2004, 20h44
  5. [Threads]Comment les organiser pour un jeu du serpent ?
    Par Pill_S dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 11/05/2004, 15h22

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