Bonjour,
Il s'agit d'afficher une Listbox qui propose une complémentation au mot saisi en cours sur un widget Text.
L'affichage de la Listbox doit être temporaire et j'aimerais que le bind '<Down>' soit effectif uniquement pendant l'affichage de la Listbox.
J'ai essayé avec objet.after(...) et des variables pour tester si il y a une action en cours ou non, mais visiblement, je n'ai pas tout compris. Que dois-je alors modifier dans le code ci-dessous?
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
import tkinter
 
class Gestion_feuille():
 
    def __init__(self):
        self.root = tkinter.Tk()
        self.compl_flag=tkinter.BooleanVar(0)
        self.root.title("Essai de complémentation")
        self.texte1 = tkinter.Text(self.root, wrap=tkinter.WORD)
        self.texte1.pack()
        self.liste_complement=tkinter.Listbox(self.root)
 
        self.liste_complement.bind('<Return>',self.remplacement_complement_direct)
 
        self.texte1.bind('<KeyRelease>', self.proposition_liste)
        self.texte1.bind('<Control-Down>', self.selection_liste_proposition)
        self.texte1.bind('<Control-space>', self.remplacement_complement_direct)
        self.texte1.focus_set()
        self.root.mainloop()
 
 
    def affichage_liste(self,event=None):
        ligne_fin=float(self.texte1.index(tkinter.END))
        ligne_insertion=float(self.texte1.index(tkinter.INSERT))
        self.position=self.texte1.index(tkinter.INSERT)
        if ligne_fin-ligne_insertion<1:
            self.texte1.insert(tkinter.END,'\n')
#        if not self.compl_flag.get():
#            self.compl_flag.set(1)
#        else:
#            self.texte1.after(3000, self.affichage_liste)
#            return
        self.position_liste=self.position + '+1l'
#        self.texte1.bind('<Down>', self.selection_liste_proposition)
        self.texte1.window_create(self.position_liste,align=tkinter.TOP,window=self.liste_complement)
        self.texte1.mark_set("insert", self.position)        
#        self.texte1.after(3000,self.effacement_liste)
 
    def effacement_liste(self,event=None):
#        self.liste_complement.forget()
        self.texte1.focus_set()
#        self.compl_flag.set(0)
 
    def selection_balise_mot(self,event=None):
        """Délimite les balises le mot en cours par des balises"""
        position=self.texte1.index(tkinter.INSERT)
        delimitateur=r'[\s\n0-9<>,?;.:/!*&~#\"\'\-_\^@°=+{}()\[\]\|]'
        position_fin=self.texte1.search(delimitateur,index=position,stopindex=tkinter.END,regexp=1,count=1)
        position_debut=self.texte1.search(delimitateur,index=position,stopindex="1.0",backwards=1,regexp=1,count=1)
        if position_debut=="":
            position_debut="1.0"
        return position_debut,position_fin
 
    def recuperation_mot_saisi(self,event=None):
        """Fonction qui permet de récupérer le dernier <<mot>> qui est entrain d'être saisi"""
        [position_debut,position_fin]=self.selection_balise_mot()
        if position_debut=="1.0":
            mot_saisi=self.texte1.get(position_debut,position_fin)
        else:
            mot_saisi=self.texte1.get(position_debut+'+1c',position_fin)
        return mot_saisi
 
    def mots_pour_complements(self):
        """Liste des mots de complémentation"""
        liste_mots=['peut-être','essaie','si et seulement si','il faut et il suffit',r'\frac{}{}']
        return liste_mots
 
 
    def recherche_complement(self,saisie,liste_mots):
        """Saisie: le mot en cours saisie , liste de mots: la liste exhaustive et liste_complement_recherche: la selection des mots"""    
        liste_complement_recherche=[]
        for index in range(len(liste_mots)):
            if saisie in liste_mots[index]:
                liste_complement_recherche.append(liste_mots[index])
        return liste_complement_recherche
 
    def proposition_liste(self,event=None):
            mot_saisi=self.recuperation_mot_saisi()
            liste_mots=self.mots_pour_complements()
            self.liste_complement_proposition=self.recherche_complement(mot_saisi,liste_mots)
            self.liste_complement.delete(0,tkinter.END)
            for index in range(len(self.liste_complement_proposition)):
                self.liste_complement.insert(tkinter.END,self.liste_complement_proposition[index])
            self.liste_complement.selection_set(0,0)
            self.affichage_liste()            
 
    def selection_liste_proposition(self,event=None):
        """Si l'utilisateur tape <'Ctrl+Down'> on positionne le focus sur la liste des mots"""
        self.position_texte=self.texte1.index(tkinter.INSERT)
        self.liste_complement.focus_set()
 
    def remplacement_complement_direct(self,event=None):
        mot_select=self.liste_complement.get(self.liste_complement.curselection())
        indice=self.liste_complement.index(self.liste_complement.curselection())
        self.texte1.focus_set()
        if indice!=0:
            self.texte1.mark_set(tkinter.INSERT,self.position_texte)
        mot_saisi=self.recuperation_mot_saisi()
        [position_debut,position_fin]=self.selection_balise_mot()
        if position_debut!="1.0":
            position_debut=position_debut+'+1c'
        self.texte1.delete(position_debut, position_fin)
        self.texte1.insert(tkinter.INSERT,mot_select)
 
if __name__ == '__main__':
    Gestion_feuille()
Par ailleurs, petit pb subsidiaire... la Listbox se positionne sur la ligne du dessous mais ne suit pas l'évolution du texte tapé alors que j'ai fait
<<self.position+'+1l'>>

Puis autre problème... lorsque l'on tape 2 lignes sur le widget Text et qu'on revient sur la première ligne, la Listbox décale et coupe la deuxième ligne...

Merci pour vos réponses.

Gabriel