valaquarus | #31 Posté le 1/7/2022 à 16:57:10 |
---|
-- Unus Ex Altera -- | @Patrick, dans le petit essai que j'ai réalisé, l'affichage en premier est en value (petit raccourci) quand je tape entrée on passe en mode affichage avec format (donc string) si je retape entrée on passe à nouveau en mode saisie sans format (value), ça fonctionne et c'est exactement ce que je voulais où alors tu es en train de me dire que dans cinq secondes cette machine va s'autodétruire (sur un air connu). Philippe Télécharge (si tu as le temps) howmuch4 depuis la forge, tu comprendra ce que je voulais obtenir. En tout cas je te remercie encore de ton accompagnement car j'ai appris beaucoup et j'ai franchi un certain seuil lié au peu que je connaissais en programmation structurée pour osé venir sur les terres de la POO.Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
Patrick | #32 Posté le 2/7/2022 à 09:12:29 |
---|
| La programmation n'a pour limite que notre imagination, juste pour le fun essaie ça :
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
| INHERITS TextBox EXPORT
PRIVATE $value AS FLOAT ''contient la valeur numérique PRIVATE $reg AS STRING ''contient les expressions réguliéres PRIVATE $format AS STRING ''contient le formatage de la variable PRIVATE $regex AS NEW RegExp ''controle l'entrée, il faut activer gb.pcre PRIVATE $lab AS Label
PUBLIC CONST num AS STRING = "-?[0-9]*[,]?[0-9]*" ''valeur numérique entrée au clavier. Si on veut le point et la virgule : "-?[0-9]*[,.]?[0-9]*" mais il faudra faire attention à la conversion
PROPERTY Value AS FLOAT ''valeur float de la textbox PROPERTY Format AS STRING ''on passe le format que l'on souhaite voir en sortie
PUBLIC SUB _new()
DIM obs AS Observer obs = NEW Observer(ME) AS "obs" 'on observe les event de la textbox $reg = num 'par défault c'est un numérique que on rentre, on pourrait mettre plusieurs constantes $regex.Compile($reg) 'on pre compile pour gagner du temps $lab = NEW Label(ME.Parent) $lab.Alignment = Align.Right END
PUBLIC SUB obs_Lostfocus() 'lorsque la textbox perd le focus on met en forme selon le format passé IF ME.Text THEN $value = Val(ME.Text) IF $format THEN Object.Lock(ME) 'on verrouille l'objet pour que l'event change ne soit pas appelé ME.Text = Format($value, $format) Object.Unlock(ME) 'on deverouille l'objet ENDIF ELSE ME.Clear ENDIF $lab.Visible = FALSE
END
PUBLIC SUB obs_Gotfocus() 'lorsque le texbox prend le focus on retansforme la valeur en string IF $value = 0 THEN ME.Clear ELSE ME.Text = Str($value) $lab.x = ME.X $lab.y = ME.Y + ME.H $lab.h = ME.H $lab.w = ME.W $lab.Visible = TRUE
END
PUBLIC SUB obs_change() 'lorsque la textbox change de valeur on vérifie si le texte correspond IF ME.Text THEN 'l'erreur est provoquée par un me.text null, c'est mieux de tester que dd'utiliser un try $regex.Exec(ME.Text) ME.Text = $regex.Text 'si mon entrée au clavier ne correspond pas au patern seul la partie juste est retournée ELSE $value = 0 ENDIF IF ME.Text AND IF $format THEN $lab.Text = Format(Val(ME.Text), $format) ENDIF END
PRIVATE FUNCTION Value_Read() AS FLOAT
RETURN $value
END
PRIVATE SUB Value_Write(Value AS FLOAT)
IF $format THEN ME.text = Format(Value, $format) $value = Value
END
PRIVATE FUNCTION Format_Read() AS STRING
RETURN $format
END
PRIVATE SUB Format_Write(Value AS STRING)
$format = Value
END
|
|
valaquarus | #33 Posté le 2/7/2022 à 10:52:41 |
---|
-- Unus Ex Altera -- | @Patrick Salut, j'avais fait une version similaire (pas avec un label mais un textbox) une zone pour la saisie et une zone pour l'affichage formaté qui fonctionnait bien avec le même résultat. Là j'en suis a essayé d'avoir plusieurs constantes légèrement différentes que je voudrais transmettre (une à la fois) à la class pour modifier l'affichage formaté. Je réussi facilement sur la transmission du format d'affichage puisqu'il suffit de class.format="un truc" mais je coince sur la transmission de la constante contenant l'expression régulière. Je ne sais pas instancier correctement la bête. PhilippeSystème d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
valaquarus | #34 Posté le 2/7/2022 à 12:44:39 |
---|
-- Unus Ex Altera -- | @Patrick, c'est fou jusqu'où tu m'as poussé. L'instanciation était ma plus grande phobie et je découvre et m'amuse. Une autre variante (version 5) d'une class nommée (très modestemment) tbxPerso :
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
| ' Gambas class file
INHERITS TextBox '<--------------------------------------------------------- Tout l'héritage du composant TextBox '<----------------------------------------------------------------------------- (Export) pour créer la class dans l'IDE EXPORT '<------------------------------- remarquez les doubles '' pour faire apparaître les commentaires en explication des objets dans l'IDE PRIVATE $value AS FLOAT ''Contient la valeur numérique PRIVATE $regPat AS STRING ''Pattern des expressions réguliéres PRIVATE $format AS STRING ''Contient le formatage de la variable PRIVATE $regex AS NEW RegExp ''Contrôle l'entrée, il faut activer gb.pcre PRIVATE $bFocus AS BOOLEAN ''Boolean du focus PRIVATE $listview1 AS ListView PRIVATE $TextBox2 AS TextBox
PUBLIC CONST sNumVirgule0 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,0}$" '<--------- ensemble de constantes représentant une expression régulière PUBLIC CONST sNumVirgule1 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,1}$" PUBLIC CONST sNumVirgule2 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,2}$" '<--------- le format doit suivre l'expression régulière PUBLIC CONST sNumVirgule3 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,3}$" PUBLIC CONST sNumVirgule AS STRING = "^-?[0-9]*[,.]?[0-9]*$"
PUBLIC Liste AS NEW String[] PUBLIC ListeC AS NEW String[] PUBLIC ListeB AS NEW String[]
'<------------------- Début propriétés ajoutées à TextBox --------------------- PROPERTY Value AS FLOAT ''Valeur float de la textbox PROPERTY Format AS STRING ''On passe le format que l'on souhaite voir en sortie
PRIVATE SUB Value_Write(Value AS FLOAT) '<------------------------------------- la propriété Value de notre TextBox
$value = Value '<--------------------------------------------------------- récupération de la valeur et transmision à la variable locale
END
PRIVATE FUNCTION Value_Read() AS FLOAT '<------------------------------------- la propriété Value de notre TextBox
RETURN $value '<---------------------------------------------------------- renvoi de la propriété
END
PRIVATE SUB Format_Write(sFormat AS STRING) '<------------------------------- la propriété Format de notre TextBox
$format = sFormat '<------------------------------------------------------ récupération de la valeur et transmision à la variable locale
END
PRIVATE FUNCTION Format_Read() AS STRING '<--------------------------------- la propriété Format de notre TextBox
RETURN $format '<--------------------------------------------------------- renvoi de la propriété
END '<-------------------- Fin propriétés ajoutées à TextBox ----------------------
PUBLIC SUB _new()
DIM obs AS Observer DIM listview1 AS Observer DIM sCste AS STRING DIM i AS INTEGER
obs = NEW Observer(ME) AS "obs" '<----------------------------------------- nouvel observateur pour récupérer les évènements
$listview1 = NEW ListView(ME.Parent) $TextBox2 = NEW TextBox(ME.Parent) listview1 = NEW Observer($listview1) AS "listview1"
$listview1.ShowCheck = TRUE $listview1.X = 7 $listview1.Y = 7 $listview1.h = 150 $listview1.w = 250 $listview1.Visible = TRUE
$TextBox2.X = 7 $TextBox2.Y = 158 $TextBox2.H = 35 $TextBox2.W = 250 $TextBox2.Visible = TRUE $TextBox2.ReadOnly = TRUE
Liste = [snumVirgule0, sNumVirgule1, sNumVirgule2, sNumVirgule3, sNumVirgule] '<----- liste des expressions régulières ListeC = ["$#,###", "$#,###.#", "$#,###.##", "$#,###.###", "$#,###.#######"] '<------------- liste des formats ListeB = ["Valeur Numérique sans décimale""Valeur Numérique à une décimale", "Valeur Numérique à deux décimales", "Valeur Numérique à trois décimales", "Valeur Numérique à virgule"] '<----------------------------------------------------- liste des explications
i = 0 FOR EACH sCste IN Liste $ListView1.Add(CStr(i), sCste) INC i NEXT
$ListView1.Key = Liste.Find(sNumVirgule) listview1_select() $bFocus = TRUE '<---------------------------------------------------------- initialisation du boolean
END
PUBLIC SUB listview1_select()
$regPat = $ListView1.Current.Text $TextBox2.Text = ListeB[CInt($ListView1.Key)] TransFormat($regPat) '<---------------------------------------------- format transmis à notre class en fonction de sRegTransf $regex.Compile($regPat)
END
PUBLIC FUNCTION TransFormat(valeur AS STRING) AS STRING
DIM i AS INTEGER
i = Liste.Find(valeur) IF valeur = liste[i] THEN $Format = ListeC[i] RETURN $Format
END
PUBLIC SUB obs_Change() ''Contrôle de la saisie
IF ME.text THEN '<--------------------------------------------------------- pour ne pas avoir d'erreur de texte vide $regex.Exec(ME.Text) '<--------------------------------------------- test de la valeur au crible de l'expression régulière ME.Text = $regex.Text '<--------------------------------------------- isNumber() donc on récupère chaque chiffre IF ME.Text MATCH "." THEN ME.Text = Replace(ME.Text, ".", ",") '<----- pour récupérer la virgule à partir du point IF ME.text THEN $value = Val(ME.Text) IF ME.Value > 20000000 THEN '<----------------------------------------- pour ne pas dépasser la somme ME.Value = 0 ME.Clear ME.SetFocus ENDIF ELSE $value = 0 ENDIF
END
PUBLIC SUB obs_Lostfocus() ''Le format ne sera appliqué qu'après
IF ME.Text THEN $value = Val(Format($value, "#.############")) '<------------------- on s'assure que le texte est une suite de chiffres sans format IF $format THEN Object.Lock(ME) '<------------------------------------------------- on verrouille l'objet pour ne pas appeler l'event Change ME.Text = Format($value, $format) '<----------------------------- on formate le texte comme voulu Object.Unlock(ME) '<----------------------------------------------- on deverouille l'objet ENDIF $bFocus = NOT $bFocus '<--------------------------------------------- inversion du boolean ELSE ME.Clear ENDIF
END
PUBLIC SUB obs_Gotfocus() ''Pour être certain d'avoir à la fois une valeur et un texte
IF $value = 0 THEN ME.Clear ELSE ME.Text = Format($value, "#.############") '<----------------------- on s'assure que le texte est une suite de chiffres sans format $bFocus = NOT $bFocus '<--------------------------------------------- inversion du boolean ENDIF
END
PUBLIC SUB obs_Activate() ''L'utilisateur tape sur entrée et bascule l'affichage
SELECT CASE $bFocus CASE TRUE obs_Lostfocus() '<------------------------------------------------- le composant perd le focus CASE FALSE obs_Gotfocus() '<------------------------------------------------- le composant gagne le focus END SELECT
END
|
Par contre je ne sais pas bien choisir entre Public et Private pour mes variables dans une class, j'ai tendance à tout mettre en public et ça se débrouille.
Pour les procédures je crois avoir compris que c'est en fonction de la profondeur (si cela doit être utilisé par une autre class) mais là je ne vois pas pourquoi les constantes représentant les expressions régulières sont en Public? Philippe
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
valaquarus | #35 Posté le 2/7/2022 à 14:47:26 |
---|
-- Unus Ex Altera -- | @Patrick, j'ai déposé sur la forge la nouvelle version de howmuch5 donc en version 5 qui comprend l'ajout de ton label d'affichage car pour la saisie c'est un bon guide visuel mais j'ai conservé l'affichage "final" par la touche entrée et donc par _Activate. C'est fonctionnel et ça ressemble à ce que je souhaitais. Je pourrai "exporter" ces idées dans d'autres projets avec des choix d'expressions régulières. Philippe Dans cette mouture j'ai mis tout le monde en Private et ça ne s'est pas auto-détruit.Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
Patrick | #36 Posté le 2/7/2022 à 17:24:28 |
---|
| Si on veut pouvoir changer l'expression régulière on a 2 solutions : - On rend nos constantes publiques
1
2
3
4
5
| PUBLIC CONST sNumVirgule0 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,0}$" '<--------- ensemble de constantes représentant une expression régulière PUBLIC CONST sNumVirgule1 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,1}$" PUBLIC CONST sNumVirgule2 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,2}$" '<--------- le format doit suivre l'expression régulière PUBLIC CONST sNumVirgule3 AS STRING = "^-?[0-9]*[,.]?[0-9]{0,3}$" PUBLIC CONST sNumVirgule AS STRING = "^-?[0-9]*[,.]?[0-9]*$"
|
puis on cré la propriété TextReg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| PROPERTY TextReg AS STRING
PRIVATE FUNCTION TextReg_Read() AS STRING
RETURN $regPat
END
PRIVATE SUB TextReg_Write(Value AS STRING)
$regPat = Value 'on refait l'affichage
END
|
- On utilise la class Enum :
1
2
| PUBLIC ENUM sNumVirgule0, sNumVirgule1, sNumVirgule2, sNumVirgule03, sNumVirgule PRIVATE $Liste = ["^-?[0-9]*[,.]?[0-9]{0,0}$", "^-?[0-9]*[,.]?[0-9]{0,1}$", "^-?[0-9]*[,.]?[0-9]{0,2}$", "^-?[0-9]*[,.]?[0-9]{0,3}$", "^-?[0-9]*[,.]?[0-9]*$"]
|
puis on cré la propriété TextReg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| PROPERTY TextReg AS INTEGER
PRIVATE FUNCTION TextReg_Read() AS INTEGER
RETURN $Liste.Find($regPat)
END
PRIVATE SUB TextReg_Write(Value AS INTEGER)
$regPat = $Liste[Value] 'on refait l'affichage
END
|
Dans la classe appelante le changement se fait de la même façon :
1
| MontbxPerso.TextReg = tbxPerso.sNumVirgule0
|
L'avantage de la 1° solution est qu'elle est facile à lire et à écrire L'avantage de la 2° est qu'on peut l'énumérer |
valaquarus | #37 Posté le 2/7/2022 à 18:23:10 |
---|
-- Unus Ex Altera -- | @Patrick ah que serh schöen! La première avec les constantes est pour un appel externe c'est le pourquoi des valeurs en public. Je suis très sensible à la seconde même si moins facile à lire me semble plus logique. J'avais contourné le problème avec un listview et un nouvel observer pour suivre l'évènement _Select et une fonction renvoyant le format et l'expression choisie. Par contre j'ai rendu les constantes Private et ça le fait quand même, bien sûr elles sont globales à l'intérieur de ma class et je ne peux pas les appeler de l'extérieur mais de l'intérieur, pas de souci. J'aime beaucoup l'idée de créer une nouvelle propriété. Pourquoi les observer peuvent ils être déclarés en global comme en locale :
1
2
| DIM obs AS Observer DIM listview1 AS Observer
|
Les deux fonctionnent mais je ne connais pas l'incidence de l'un et de l'autre.
1
2
| PRIVATE obs AS Observer PRIVATE listview1 AS Observer
|
PhilippeSystème d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
valaquarus | #38 Posté le 2/7/2022 à 18:46:19 |
---|
-- Unus Ex Altera -- | @Patrick, j'ai l'erreur (Missing As) pour private $List = [...] On ne peut pas faire de raccourci, ici ? Philippe
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |
valaquarus | #39 Posté le 2/7/2022 à 20:55:40 |
---|
-- Unus Ex Altera -- | @Pattrick, ça fonctionne bien! Me voilà avec deux tbxPerso, un avec les constantes et l'autre avec une énumération. Dans le premier je n'ai pas la propriété TexReg de déclarée dans la seconde, si. Philippe La différence se ferait par l'appel de l'extérieur.
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5 |