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 :

Débutant: changer d'image (à apparaître dans un canevas) via un menu [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 Débutant: changer d'image (à apparaître dans un canevas) via un menu
    Bonsoir,

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

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

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

  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 778
    Points
    36 778
    Par défaut
    Salut,

    La chose qui est affichée (par la fonction afficher) est un objet PhotoImage accédé via la variable ImgPunch. Si on veut changer la PhotoImage, il faut assigner une autre PhotoImage à cette variable.
    Et donc créer les PhotoImage correspondants.

    Ce qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def selectImage(nomFichier):
        global ImgPunch
        ImgPunch = PhotoImage(file=nomFichier)
    (que je n'ai pas testé)

    - 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 ha, mince..
    Bonjour wiztricks,
    merci pour votre réponse.

    je viens d'essayer, mais malheureusement, il semblerait que ça continue à ce mordre la queue.
    l'image ne se change pas.

    un peu comme si la fonction selectImage(nomFichier) recevait bien l'ordre de changement de imgPunch (avec "test.png" dans lobjet PhotoImage),
    mais que quand le programme ppl tourne, il repasse d'abord sur l'assignation d'imgPunch d'origine (celle par défaut avec "atome.gif") et réassigne "atome.gif" à l'objet a PhotoImage (alors que la fonction venais bien d'assigner "test.png").

    Existe il un moyen de dire , par exemple:
    "Si c'est la première fois depuis l'ouverture du programme que imgPunch est assignée placer "atome.gif"
    Sinon consulter le résultat de la fonction selectImage(nomFichier)".. ?

    Ou dire un truc comme:
    Quand la fonction selectImage(nomFichier) a retourné un résultat, l'imposer devant toute autre assignation ?

    Vais essayer avec des trucs if et else autour de l'assignation d'origine..
    Merci

  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 778
    Points
    36 778
    Par défaut
    Salut,

    Citation Envoyé par Jma06 Voir le message
    je viens d'essayer, mais malheureusement, il semblerait que ça continue à ce mordre la queue.
    l'image ne se change pas.
    Si çà ne fonctionne pas, c'est d'abord parce que j'ai orthographié la variable avec un I majuscule alors que celle qu'on veut modifier n'en a pas.
    (c'est ce que veut dire "pas testé": il y a peut être des erreurs d'orthographe).

    Et si vous vous lancez dans des théories fumeuses, c'est que vous ne maîtrisez pas les bases.
    Votre problème se ramène à une fonction g qui récupère une variable globale et une fonction f qui la met à jour.

    Côté code, çà s'écrit en quelques lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> def g():
    ...     print (a)
    ...
    >>> def f(s):
    ...     global a
    ...     a = s
    ...
    >>>
    Et là vous voyez que si j'assigne à la variable a une valeur, g va l'afficher:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> a = 1
    >>> g()
    1
    >>>
    Et si je fais cette mise à jour via f, çà marche aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> f('toto')
    >>> g()
    toto
    >>>
    Et si ces mécanismes de bases là ne sont pas acquis, programmer restera une sorte de loterie où vos programmes fonctionnent en fonction de l'humeur de je ne sais quels dieux.

    - 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 mea culpa.
    Ha oui! puréé!!
    Vous avez raison.. complètement, définitivement.
    j'ai fais copier/coller de la board ce matin et j'ai testé avec.. en effet.
    voyant le même résultat..me suis pas méfié.. je suis navré.

    Tout s'explique simplement du coup
    Oui mon incompétence me fait faire dans le fumeux j'avoue, et oui aussi, j'ai pas les bases (que j'essai d'apprendre seul).
    C'est un apprentissage qui se fait parfois dans la douleur (et dans l’humiliation comme dans ce cas) mais super stimulant.

    Je me dis que c'est a votre contact, et faisant ce genre d'erreurs (et en se faisant secouer de la sorte) qu'on fini par grandir.
    En tous cas merci pour votre temps et ce petit "secouage".
    Vous êtes un modérateur en or.

    A bientôt.
    Jean-Marie

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

Discussions similaires

  1. Changer l'image contenue dans une popup depuis la page mère
    Par markham dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 13/02/2014, 19h45
  2. Réponses: 1
    Dernier message: 06/02/2012, 14h14
  3. comment changer l'image inseré dans mon crystal reports par code?
    Par rochdi123 dans le forum Windows Forms
    Réponses: 7
    Dernier message: 04/06/2009, 13h52
  4. Changer d'image placée dans un cadre en cliquant sur un lien
    Par makalu65 dans le forum Webdesign & Ergonomie
    Réponses: 2
    Dernier message: 14/12/2008, 19h55
  5. Changer l'image affichée dans le temp
    Par Elazael dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 12/10/2008, 11h47

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