Bonjour à tous,

Bien qu'elle fonctionne parfaitement, la finalité en elle même de l'application ci-jointe n'a pas grand intérêt à part celui d'être le prétexte:

- à la manipulation des widgets
- à la factorisation des Entry et Label (courtoisie wiztricks, merci à lui)
- au contrôle de saisies float y compris négatives. (cf. post. de paussekawa)
- à la compréhension de la fabrication des classes

- mais aussi à la tentative ratée de regrouper la validation des entrées dans la classe Saisie.

Je me demande en effet (et peut être à tort d'ailleurs!) s'il ne serait pas plus judicieux, dans cet exercice, que la fonction de validation ici: 'OnValidate()' soit une s/fonction de la classe Saisie.

C'est ce que je n'ai pas réussi à faire.

je cherche un 'coup de main' et un avis à ce sujet.
A résultat final identique, ai-je employé la bonne façon pour le faire ?

A+
L.P.

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
from tkinter import *  
 
class Saisie(object):
    def __init__(self):
        "Création des Entry contôlées en quantité selon la demande "
    def crea(z):
#        print(z)
        for z in range(-1,z):
            name = 'myvars-%d' % (z+1)
            v = myvars[name] = StringVar(name=name) #; print(v,name)
            v.trace_variable("w", OnValidate)
 
            entry = Entry(root, textvariable =v, name="entry%d" %(z+1))
            entry.grid(row=z+1,column =0)
            entries.append(entry)  ## ajout dans la liste
            entry.bind('<Return>', change)
            entry.bind('<Tab>', affiche)
            entry.bind('<Shift-Tab>', affiche)
            entry.bind('<Button-1>', affiche)
            entry.bind('<Up>', changeUp)
            entry.bind('<Down>', change)
 
            etq='etq-%d' %(z+1)
            etq=Label(width=20, text='')
            etq.grid(row=z+1,column =1)
            etiq.append(etq)  ## ajout dans la liste
        e1.destroy() #; print('destroy e1')
        ee.destroy() #; print('destroy ee')
        entries[0].focus_set()
## ----       
def OnValidate(name, index, mode):
    idx=int(name[7:]); # index du nom de la StringVar
    var = myvars.get(name)
    if var.get().startswith('.'):
        q=root.focus_displayof() ## idem que les 2 lignes ci-dessus
        q.insert(0,'0.')         ## evite de rechercher l'index
    elif var.get().startswith('-.'):
        entries[idx].delete(0,END)   ## code avec l'index
        entries[idx].insert(0,'-0.') ## même résultat       
    i=0
    for c in var.get():
        i+=1
        if not c.isdigit() and c not in '.-' or (c=='-' and i > 1):
            root.event_generate('<BackSpace>')
 
    if i > 1:
        try:
            s=float(var.get())
        except:
            root.event_generate('<BackSpace>')
    root.event_generate('<End>')
## ----   
 
def change(event):
    root.event_generate('<Tab>')
 
def changeUp(event):
    root.event_generate('<Shift-Tab>')
 
def affiche(event):
    w=event.widget  # ; print(w,w.get())
    ww=str(w)
    idx=int(ww[6:]) # ; print('w.idx:',idx)
    result=0.0 ; r = 0
 
    for i in range(0,z+1):
#        print('z',z)
        ri=entries[i].get() #; ri=float(ri) ; print('ri',ri)
        if ri != '':
            r += float(entries[i].get())
            etiq[i].config(text='s/tot =  {:8.4f}'.format(r),anchor=E)
        else:
            etiq[i].config(text='')
 
        etqTotv.config(text='{:10.2f}'.format(r))
 
def valid(event=None):
    global z
    try:
        z=int(e1.get())-1
        if z <= 45: ##; print(z)
            Saisie.crea(z)
        else: e1.set(0)    
    except:
        e1.delete(0,END)
        return 0
 
### fenêtre principale ***
root = Tk()
root.title("** Additionneuse **")
 
entries = []
myvars = {}
etiq = [] 
z=100 ## nombre de lignes maxi
eeVar=StringVar()
ee=Entry(root, textvariable=eeVar, width=30)  
ee.grid(row=0,column =0)
eeVar.set('Combien de lignes ?')
e1=Entry(root, validate='focusout', vcmd=valid)
e1.grid(row=0,column =1)
e1.bind('<Return>', valid)
e1.focus_set()
 
etqTotx=Label(width=20, text='Total général:', anchor=E, font='weight -14 bold')
etqTotx.grid(row=z+2,column =0)
etqTotv=Label(font='weight -16 bold', fg='blue',width=20, text='0.0')
etqTotv.grid(row=z+2,column =1)
 
root.mainloop()