Gambas France BETA


Pas de compte ? Incription

Format d'un ValueBox

Ce sujet est résolu.

123
AuteurMessages
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.3
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.
Philippe
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.3
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.3
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.3
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

Philippe
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.3
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.3
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.3
123