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

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

  7. #7
    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
    Salut,
    je vous remercie d'avoir pris le temps de me répondre sur un sujet qui n'est pas technique, mon ego n'a pas trop souffert, ne vous inquiétez pas

    Je voulais juste vous prévenir que ce genre de remarque pourrait être blessante, de mon point de vue, sans réelle nécessité.

    Je comprends qu'on puisse se montrer cassant ou blessant lorsqu'un intervenant ne respecte pas les règles du forum, n'a pas pris le temps de lire la doc ni de chercher dans les discussions du forum mais sinon, je n'en vois pas l'intérêt. C'est peut-être à cause de mon métier d'enseignant où nous devons être vigilants par rapport à la psychologie des adolescents, ce n'est pas Samuel Paty qui me démentira

    Bien à vous.

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    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 690
    Par défaut
    Citation Envoyé par LeVraiGaulois Voir le message
    Je comprends qu'on puisse se montrer cassant ou blessant lorsqu'un intervenant ne respecte pas les règles du forum, n'a pas pris le temps de lire la doc ni de chercher dans les discussions du forum
    Dans une relation, il y a deux points de vue. Le mien où il n'y a aucune intention de se montrer blessant en vous suggérant de chercher un peu et en vous montrant que ce faisant on trouve...

    Et il n'y a aucune intention d'être blessant parce que, pour moi, chercher des solutions commence d'abord par étudier ce qu'on a déjà fait (et les moteurs de recherches sont juste là pour ça).

    Une autre approche aurait été de recopier l'exemple trouvé sur Internet et de le modifier un peu pour vous le soumettre.

    Outre que ce serait du plagiat, ça ne vous montre en rien comment trouver par vous même.

    Le votre qui est celui de quelqu'un qui a déjà bien souqué avant de se résoudre à demander de l'aide.

    Et je reconnais qu'il peut être frustrant de constater combien on a pataugé alors que la solution (ou la démarche qui permet de la trouver) n'est pas si compliquée.

    Mais tout apprentissage devient frustration si on part à prétendre faire bien alors qu'on fait juste de son mieux (et pas si bien que çà).

    Citation Envoyé par LeVraiGaulois Voir le message
    C'est peut-être à cause de mon métier d'enseignant où nous devons être vigilants par rapport à la psychologie des adolescents
    J'ai eu la chance d'être enseignant dans des lycées, des universités, ou pour des formations professionnelles. A l'université les bac+3/4 où les professionnels en entreprises veulent apprendre quelque chose et vous respectent pour ce que vous leur apportez.

    Bien sûr, si on enseigne le commerce, la psychologie,... on entre dans autre chose car on demande aux gens de "croire", on leur vend un certain regard sur le monde.

    Avec la technique (et surtout avec la programmation) on teste si on a compris, et ça marche ou ça ne marche pas. L'"enseignant" est une sorte de médiateur entre l'élève et une réalité qu'il ne découvre qu'en se jetant à l'eau.

    Avec les plus jeunes, c'est compliqué car ils sont dans la construction de leur identité et ont des difficultés à se positionner par rapport à l'autorité (quelque soit la base de son fondement).

    - 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