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 :

Widget Text de tkinter - La sélection multiple du texte est-elle possible de manière manuelle ? [Python 3.X]


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Inscrit en
    Septembre 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 8
    Par défaut Widget Text de tkinter - La sélection multiple du texte est-elle possible de manière manuelle ?
    Bonjour,

    je ne parviens pas à sélectionner avec la souris plusieurs parties éloignées d'un texte dans le widget Text alors que c'est facile de le faire par programmation.

    J'ai utilisé la méthode classique pour tenter une multi-sélection manuelle (maintien de la touche Ctrl pendant les différentes sélections à la souris).

    J'ai recherché dans la doc du widget pour voir s'il y avait un attribut en lien avec la sélection multiple mais je n'en ai pas trouvé.

    S'agit-il d'une limitation de ce widget ou y-a-t'il un moyen de réaliser une sélection multiple de manière manuelle ?

    Merci de m'avoir lu et de vos pistes éventuelles.

    TZ

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

    Citation Envoyé par LeVraiGaulois Voir le message
    S'agit-il d'une limitation de ce widget ou y-a-t'il un moyen de réaliser une sélection multiple de manière manuelle ?
    Je ne pense pas que le widget sache faire cela en natif.

    Mais on peut toujours le programmer.

    Il faut définir le dialogue utilisateur pour savoir qu'il veut faire plusieurs sélections et quand il a terminé. Puis on utilise la selection "normale" (ou on la recode) et on marque le texte des selections successives avec un tag ad hoc (ou avec tk.SEL qui est celui de la sélection "standard").

    En cherchant un peu vous devriez trouvez des codes qui le font déjà.

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

  3. #3
    Membre habitué
    Homme Profil pro
    Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Inscrit en
    Septembre 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 8
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Je ne pense pas que le widget sache faire cela en natif.
    - W
    D'accord, merci, je m'en doutais un peu.

    Citation Envoyé par wiztricks Voir le message
    En cherchant un peu vous devriez trouvez des codes qui le font déjà.
    - W
    J'ai déjà cherché mais mon niveau actuel (débutant) ne me permet peut-être pas de chercher correctement. Si vous pouviez préciser concrètement en quoi consiste le début de votre piste, je pourrais savoir si je suis un peu, ou trop largué :

    Citation Envoyé par wiztricks Voir le message
    Il faut définir le dialogue utilisateur pour savoir qu'il veut faire plusieurs sélections...
    - W
    TZ

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

    Citation Envoyé par LeVraiGaulois Voir le message
    Si vous pouviez préciser concrètement en quoi consiste le début de votre piste, je pourrais savoir si je suis un peu, ou trop largué
    Si vous cherchiez un peu sur Internet, vous trouveriez des exemples comme ici. Et vous étudiez le code.

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

  5. #5
    Membre habitué
    Homme Profil pro
    Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Inscrit en
    Septembre 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Physique et chimie depuis 1983 mais Langage Python depuis juin 2021
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 8
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Si vous cherchiez un peu sur Internet, vous trouveriez des exemples comme ici. Et vous étudiez le code.
    - W
    Bonjour wiztricks et merci pour ce lien très utile qui a permis de débloquer la situation.

    J'ai pu ajouter les fonctionnalités manquantes :

    • correction de sélection lors d'un changement de sens du glissement
    • prise en compte du double-clic


    Votre remarque un peu assassine sur le manque de recherche de ma part ne surprendra pas ceux qui vous lisent régulièrement (un expert en informatique n'est pas toujours expert en diplomatie ou en psychologie humaine). Sur le fond, vous n'avez pas entièrement raison car vous m'envoyez vers un site anglophone alors que nous sommes sur une site francophone, vous occultez (volontairement ou pas?) toutes mes recherches en langue française. Je reconnais qu'il ne faut pas se cantonner à la langue française puisque les langages informatiques utilisent du vocabulaire anglais mais je n'ai pas toujours le vocabulaire en anglais technique me permettant de faire des recherches pertinentes dans cette langue.

    Voici mon code, il enrichira un peu l'offre francophone qui est très pauvre sur le sujet (je n'ai pas conservé la possibilité d'effacer les parties sélectionnées du texte car cette fonctionnalité ne sera pas utile dans mon projet).

    N'hésitez pas à signaler un défaut ou à donner un conseil, quel qu'il soit.
    Cordialement,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    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
     
    import tkinter as tk
     
    class SelectableText(tk.Text):
     
        def __init__(self, master, **kwarg):
            super().__init__(master, **kwarg, wrap='word')
            self.focus_set()                                                                             # pour donner le focus sur le texte dès le démarrage de l'appli
            self.tag_configure("monTag", background="#fcc",
                                  font ="")
            # cur_ind = index courant variable au cours du glissement , max_ind = index maxi , min_ind = index mini et down_ind = index du texte lors d'un clic down
            self.cur_ind = self.max_ind = self.min_ind = self.down_ind = ''      #  initialisation par précaution mais ce sera fait de manière plus pertinente dans la méthode mouse_down
     
            self.bind("<Control-Button-1>", self.mouse_down)
            self.bind("<Button-1>", self.mouse_down)                                        # pour obliger les variables à être définies même si la touche Ctrl n'est pas enfoncée juste avant le down
            self.bind("<Control-B1-Motion>", self.mouse_drag)                         # pour obliger l'appui sur la touche control pdt le glissement
            self.bind("<ButtonRelease-1>", self.mouse_up)
            self.bind("<KeyRelease-Control_L>", self.mouse_up)
            self.bind("<Control-Double-Button-1>", self.double_click)
     
        def double_click(self, event):
            pattern = "[\s,;:!?.\"'()]"                                                                 # regex permettant de détecter le caractère de transition entre deux mot (espaces, virgule, point...)
            self.debut_mot = self.index(f"@{event.x},{event.y} wordstart")        
            self.fin_mot = self.search(pattern, self.debut_mot, regexp = True, forwards=True)
            self.tag_add(tk.SEL, self.debut_mot, self.fin_mot)
     
        def mouse_down(self, event):
            self.down_ind = self.index(f"@{event.x},{event.y}")                         #  '@x,y' est la position située juste avant le caractère le plus proche de la position (x, y)
            self.cur_ind = self.max_ind = self.min_ind = self.down_ind
     
        def update_ind(self):                                                                          # permet de mettre à jour les index et la sélection en cours en réduisant éventuellement une sélection trop grande lors d'une inversion du glissement
            def verif_and_compare(i1 , op , i2):
                if not i1 or not i2:                                                                        # permet de vérifier si les deux index sont définis avant de les comparer
                    return False
                result = self.compare(i1, op, i2)             
                return self.compare(i1, op, i2)                                                      # compare les positions de deux index du widget texte, et retourne True si la relation précisée par op entre les deux index est vérifiée
     
            if verif_and_compare(self.cur_ind, ">", self.down_ind):                     
                self.tag_add(tk.SEL, self.down_ind, self.cur_ind)   
                if verif_and_compare(self.max_ind, ">" , self.cur_ind) :               # se produit quand on revient à G après être allé à D
                    self.tag_remove(tk.SEL, self.cur_ind , self.max_ind)    
                self.max_ind = self.cur_ind
            elif verif_and_compare(self.cur_ind , "<" , self.down_ind) :
                self.tag_add(tk.SEL, self.cur_ind, self.down_ind)
                if verif_and_compare(self.min_ind, "<" , self.cur_ind) :                # se produit quand on revient à D après être allé à G
                    self.tag_remove(tk.SEL, self.min_ind, self.cur_ind)
                self.min_ind = self.cur_ind
            elif verif_and_compare(self.cur_ind , "==" , self.down_ind)  :
                if verif_and_compare(self.min_ind, "<", self.cur_ind) :                  # se produit quand on revient à D après être allé à G
                    self.tag_remove(tk.SEL, self.min_ind, self.cur_ind)
                elif verif_and_compare(self.cur_ind, "<" , self.max_ind) :              # se produit quand on revient à G après être allé à D
                    self.tag_remove(tk.SEL, self.cur_ind, self.max_ind)
                self.cur_ind = self.max_ind = self.min_ind = self.down_ind             # on peut imposer l'index du mouse-down à tous les autres index dans ce cas
     
        def mouse_drag(self, event):
            self.cur_ind = self.index(f"@{event.x},{event.y}")
            self.update_ind()
     
        def mouse_up(self, event):        
            self.cur_ind = self.index(f"@{event.x},{event.y}")        
            self.update_ind()                                                              
            self.max_ind = self.min_ind = self.cur_ind = self.down_ind = "" 
     
        def agirSurSelection(self , action):
            sel_zones = [str(z) for z in self.tag_ranges(tk.SEL)]
     
            for i in range(0,int(len(sel_zones)-1), 2):
                startSel , endSel = sel_zones[i] , sel_zones[i+1]
                if action == "tag_add":
                    self.tag_add("monTag", startSel, endSel)
                elif action == "tag_remove":
                    self.tag_remove("monTag", startSel, endSel)
     
     
    root = tk.Tk()
    root.title("Sélection multiple avec le widget Text de tkinter")
     
    text = SelectableText(root, width=80, height=30)
     
    me = '''Mode d'emploi de l'interface :
    Pour réaliser une sélection multiple, il faut utiliser la méthode
    classique, c'est à dire maintenir la touche Ctrl tout en effectuant
    l'une des deux actions suivantes :
     
    1 - cliquer avec le bouton de gauche puis faire "glisser" le curseur
    de la souris sur le texte à sélectionner, relâcher le clic avant de
    passer à une autre partie du texte.
     
    2 - double-cliquer sur chacun des mots à sélectionner.
     
    Les parties sélectionnées peuvent être mises en forme(taguées)
    simultanément en cliquant sur le bouton correspondant.
    Un autre bouton permet de supprimer la mise en forme de toutes
    les parties sélectionnées.
     
    Remarque : l'utilisation de la touche Ctrl avant de double-cliquer sur
    un mot permet d'éviter la sélection des signes de ponctuation alors
    que le double-clic provoque leur sélection lorsque la touche Ctrl n'est
    pas enfoncée.
     
    Exemple : tester chaque méthode du double clic avec le mot suivant :
                      
                             ,ponctuation?
                             
    '''
     
    text.insert('end', me)
     
     
    bTagSel = tk.Button(root, text = "Tag select", command = lambda arg="tag_add" : text.agirSurSelection(arg))
    bDetagSel = tk.Button(root, text = "Detag select", command = lambda arg="tag_remove" : text.agirSurSelection(arg))
     
    text.grid(row=0, column=0, rowspan =3)
    bTagSel.grid(row=0, column=1)
    bDetagSel.grid(row=1, column=1)
     
    root.mainloop()

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

    Citation Envoyé par LeVraiGaulois Voir le message
    Sur le fond, vous n'avez pas entièrement raison car vous m'envoyez vers un site anglophone alors que nous sommes sur une site francophone, vous occultez (volontairement ou pas?) toutes mes recherches en langue française.
    Moi ce que je constate, c'est que vous avez pu profiter de l'article indiqué.
    Et si vous voulez vous mettre une balle dans le pied en ne cherchant que sur les sites français, c'est d'abord vous que ça pénalise.

    Citation Envoyé par LeVraiGaulois Voir le message
    (un expert en informatique n'est pas toujours expert en diplomatie ou en psychologie humaine).
    Un sujet technique est un sujet technique.

    Et l'occident s'est attaché, depuis le siècle des Lumières, à aborder les réalités techniques d'un point de vue "objectif" en faisant abstraction de la perception humaine.

    On peut le déplorer mais c'est comme çà: pas de place pour l'égo. D'autant qu'un forum est assez pauvre côté relationnel.

    On ne sait pas trop qui vous êtes, dans quel état d'esprit vous posez question ou problème, les démarches que vous avez pu faire, la formation que vous avez...

    On peut juste revisiter le problème technique posé en y appliquant son savoir faire et en essayant de se mettre à votre niveau (ce qui n'est pas toujours facile).

    Après si vous ne savez pas trop mettre une certaine distance entre un sujet technique et votre ego, c'est dommage pour vous.

    - 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. Ma sélection jquery est elle possible ?
    Par ambi86 dans le forum jQuery
    Réponses: 5
    Dernier message: 22/02/2016, 21h26
  2. Réponses: 0
    Dernier message: 01/03/2014, 10h09
  3. Réponses: 7
    Dernier message: 19/09/2012, 12h27
  4. Réponses: 6
    Dernier message: 26/04/2010, 13h44
  5. [Tkinter] widget Text
    Par t_om84 dans le forum Tkinter
    Réponses: 8
    Dernier message: 17/06/2005, 09h30

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