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 :

Récupérer rapidement et instantanément les items d'un canvas en passant la souris avec le bouton 1 appuyé


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut Récupérer rapidement et instantanément les items d'un canvas en passant la souris avec le bouton 1 appuyé
    Salut tout le monde,

    Voilà j'ai un petit soucis avec mon GUI Tkinter.
    J'ai un canvas, qui est composé de plein d'item (rectangles et lettres) et j'aimerai lorsque récupérer le nom des items pour changer leurs couleurs lorsque je passe ma souris dessus en ayant le bouton droit d'appuyer.
    J'ai réussi à faire quelques choses mais j'ai un soucis et je pense que j'ai donc pas utilisé la bonne solution car lorsque je passe ma souris dessus lentement ça fonctionne mais lorsque je passe rapidement je ne sélectionne pas tous les items (1 sur 2 voir 1 sur 3 si je passe très vite.

    Voici un morceau de mon code

    event vient de cette fonction :
    canvas.bind('<B1-Motion>', lambda event,a="B1m":self.select(event, a))

    et voici la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def select(self, event, typeofevent):
       #=======================================================================
       # get the canvas object 
       #=======================================================================
       canvas = event.widget
     
       #=======================================================================
       # find object close to mouse
       #=======================================================================
       x = canvas.canvasx(event.x)
       y = canvas.canvasy(event.y)
       item =  canvas.find_closest(x, y, halo=None, start=None)
    Ce code fonctionne mais lorsque je bouge la souris trop vite, je manque des items. Je pense que self.select est appelé toutes les Xmillisecondes du coup quand je vais trop rapidement je manque quelques items.
    Auriez vous une solution à m'indiquer pour palier ce problème ? J'aimerai récupérer instantanément et directement les items lors ma souris avec le bouton enfoncé passe dessus.

    Merci beaucoup pour votre aide et vos conseils par avance,

    Eduard

  2. #2
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    tu peux te servir de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    c = 5 #par exemple
    lst = canvas.find_overlapping(x-c, y-c, x+c, y+d)
    item = None
    if lst:
        item = lst[0]
    c étant le côté de ton rectangle d'encombrement. Tu paramétras c en fonction de la précision que tu veux avoir.
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Merci pour ta réponse afranck64.

    J'ai implémenté ta fonction mais j'ai le même problème. Lorsque je tire un grand coup de souris, ça ne sélectionne que 1 item sur 2 ou 3

    par exemple voici mon canvas qui est composé de plein de text indépendant :
    AZERTYUIOPQSDFGHJKLMWXCVBN

    Je veux en quelques sorte pouvoir les surlignés comme on surligne un texte dans un éditeur.
    Du coup j'utilise ça, qui appelle ma fonction à chaque fois que le bouton est appuyé en continue mais il ne l'appelle que tous les X millisecondes du coup quand je trace trop vite il en oublie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    canvas.bind('<B1-Motion>', lambda event,a="B1m":self.select(event, a))
    Est ce vous pensez qu'il y a une meilleure solution pour faire ça ?
    Merci encore

  4. #4
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Est-il vraiment nécessaire de se servir de l'event "motion"?

    J'aurais opté pour un "press" et "release".
    à "press" je prend le point (a, b)
    à "release" je prend le point (c, d)
    je fais un Canvas.find_overlapping(a, b, c, d)
    et je traite tous les items trouvé.

    Tu peux entre autres vérifier la hauteur de ton rectange au cas où.
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Je me sers de motion car je veux pendant que mon bouton est enfoncé sélectionner les items pour changer leurs couleurs, j'ai besoin de quelques choses de dynamique exactement comme quand on surligne un texte avec la souris.

    Merci encore pour ton aide

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Grace à l'aide d'afranck64 voici un code exemple solution écrit par afranck64. Il faut gérer uniquement le press, release des boutons, avec une fonction d'update pour calculer à chaque fois l'overlapping.
    Merci afranck64 !!!

    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
    try:
        import Tkinter as tk
    except:
        import tkinter as tk
     
    import random
     
    root = tk.Tk()
    root.title("Demo - Canvas")
    width = 100
    height = 50
    can = tk.Canvas(root,bg="white", width=width, height = height)
    can.pack()
    lst_items = []
    started = False
    start_pos = None
     
    for i in range(50):
        x = random.randint(0, width)
        y = random.randint(0, height)
        can.create_text(x, 0, text="A")
     
    def start(event=None):
        global started, start_pos
        start_pos = event.x, event.y
        started = True
        print("started")
     
    def end(event=None):
        global lst_items, started
        print("ended")
        started = False
        for item in lst_items:
            can.itemconfig(item, fill="black")
        lst_items = []
     
    def update(event=None):
        global started, lst_items
        print (started)
        if started:
            """
            x, y = event.x, event.y
     
            """
            a,b = start_pos
            c,d = event.x, event.y
            tmp = can.find_overlapping(a,b,c,d)
            for item in lst_items:
                can.itemconfig(item, fill="black")
     
            for item in tmp:
                can.itemconfig(item, fill="green")
            lst_items = tmp
     
     
     
    can.bind("<Motion>", update)
    can.bind("<ButtonPress>", start)
    can.bind("<ButtonRelease>", end)
    root.mainloop()

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 748
    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 748
    Par défaut
    Salut,

    Citation Envoyé par Mistervanhalen Voir le message
    par exemple voici mon canvas qui est composé de plein de text indépendant :
    AZERTYUIOPQSDFGHJKLMWXCVBN
    Si c'est une sorte d'éditeur de texte, on sélectionne des sous ensembles de lignes. Genre: AZERTYUIOPQSDFGHJKLMWXCVBN

    Mais lorsque la souris passe d'une ligne à l'autre, on obtient (avec des bbox):
    AZERTYUIOPQSDFGHJKLMWXCVBN
    AZERTYUIOPQSDFGHJKLMWXCVBN

    Alors qu'on voudra peut être avoir:
    AZERTYUIOPQSDFGHJKLMWXCVBN
    AZERTYUIOPQSD
    FGHJKLMWXCVBN

    => si les items du canvas représentent du texte, les caractères sont repérés par (ligne, position). La souris se déplace lorsqu'on a changé de caractère et l'ensemble des "caractères" "entre" deux positions ne sera pas toujours défini par le rectangle (bbox) correspondant.

    - 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. Récupérer tous les items d'une ListView ou d'un Adapter
    Par rolandl dans le forum Composants graphiques
    Réponses: 4
    Dernier message: 21/12/2012, 12h33
  2. [Débutant] Récupérer les items d'une listbox
    Par melleb dans le forum Interfaces Graphiques
    Réponses: 6
    Dernier message: 19/05/2011, 15h24
  3. BDC récupérer tous les items d'une application depuis le code
    Par tigrou2405 dans le forum Développement Sharepoint
    Réponses: 1
    Dernier message: 20/01/2011, 15h37
  4. Réponses: 10
    Dernier message: 26/08/2010, 01h11

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