Differenze tra le versioni di "InvBox"
(Una versione intermedia di uno stesso utente non è mostrata) | |||
Riga 53: | Riga 53: | ||
Noi per il nostro widget abbiamo bisogno di aggiungere la proprietà Invito quindi scriviamo appena sotto a Inherits UserControl: | Noi per il nostro widget abbiamo bisogno di aggiungere la proprietà Invito quindi scriviamo appena sotto a Inherits UserControl: | ||
Public Const _Properties As String = "*,Invito" | Public Const _Properties As String = "*,Invito" | ||
− | L'asterisco dice a Gambas che il nostro componente | + | L'asterisco dice a Gambas che il nostro componente mostra tutte le proprietà di ''UserControl'' e in più gli dice di aggiungere la proprietà Invito. Badate bene ''UserControl'' non vuol dire ''TextBox'' che se voi volete dal vostro componente esattamente tutte le proprietà di una ''TextBox'' con in più la proprietà ''Invito'' dovrete digitare tutte le proprietà che distinguono la ''TextBox'' rispetto al controllo base. |
Aggiungiamo: | Aggiungiamo: | ||
Riga 75: | Riga 75: | ||
o qualunque nome vi aggrada. | o qualunque nome vi aggrada. | ||
− | In questo caso non fatelo, così il nostro componente verrà caricato insieme agli altri | + | In questo caso non fatelo, così il nostro componente verrà caricato insieme agli altri controlli grafici classici di base nella scheda ''Form''. |
Ora, a seguire, diremo a Gambas quali oggetti abbiamo intenzione di usare per costruire il nostro componente, come detto useremo una ''TextBox'' e una ''Label'' ma non possiamo usare la ''Label'' come contenitore della ''TextBox'' o viceversa infatti come potete ben vedere dalla scheda ''Container'' nessun controllo può essere usato come contenitore. Il più comodo contenitore è senz'altro ''Panel'' e infatti useremo questo per il nostro controllo. | Ora, a seguire, diremo a Gambas quali oggetti abbiamo intenzione di usare per costruire il nostro componente, come detto useremo una ''TextBox'' e una ''Label'' ma non possiamo usare la ''Label'' come contenitore della ''TextBox'' o viceversa infatti come potete ben vedere dalla scheda ''Container'' nessun controllo può essere usato come contenitore. Il più comodo contenitore è senz'altro ''Panel'' e infatti useremo questo per il nostro controllo. | ||
Riga 93: | Riga 93: | ||
<Font Color=gray><B>'' <I>Mostra la frase digitata.</i></b></font> | <Font Color=gray><B>'' <I>Mostra la frase digitata.</i></b></font> | ||
Property Text As String | Property Text As String | ||
− | |||
<Font Color=gray><B>'' <I>Viene invocato ad ogni cambiamento nel testo.</i></b></font> | <Font Color=gray><B>'' <I>Viene invocato ad ogni cambiamento nel testo.</i></b></font> | ||
Event Change | Event Change | ||
Riga 108: | Riga 107: | ||
$hTxt.Background = Color.TextBackground | $hTxt.Background = Color.TextBackground | ||
$hTxt.Foreground = Color.RGB(150, 150, 150) | $hTxt.Foreground = Color.RGB(150, 150, 150) | ||
− | $hTxt.Padding = 5 | + | $hTxt.Padding = 5 |
+ | Me.Proxy = $hTbox | ||
End | End | ||
Con questo noi abbiamo detto a Gambas che il nostro componente è racchiuso in un Panel, con ''arrangement'' a ''fill'' egli espande completamente alle sue misure ciò che contiene. | Con questo noi abbiamo detto a Gambas che il nostro componente è racchiuso in un Panel, con ''arrangement'' a ''fill'' egli espande completamente alle sue misure ciò che contiene. | ||
Riga 117: | Riga 117: | ||
Con il padding alla label sincronizziamo i testi di entrambi i controlli. | Con il padding alla label sincronizziamo i testi di entrambi i controlli. | ||
+ | |||
+ | Con ''Proxy'' passiamo al nostro controllo le proprietà e gli eventi base di ''UserControl'', potete vederne la lista nella guida in linea facendo ''F2'' sulla parola all'interno della IDE. | ||
Riga 125: | Riga 127: | ||
Else | Else | ||
$hTxt.Text = "" | $hTxt.Text = "" | ||
− | Endif | + | Endif |
Raise Change | Raise Change | ||
End | End | ||
− | Utilizziamo l'evento | + | Utilizziamo l'evento interno proprio della ''TextBox'' per mostrare o nascondere il testo di invito e per propagare con ''Raise'' l'evento ''Change'' al nostro componente. |
+ | |||
Continuiamo: | Continuiamo: | ||
Riga 137: | Riga 140: | ||
Private Sub Invito_Write(Value As String) | Private Sub Invito_Write(Value As String) | ||
$sInvito = Value | $sInvito = Value | ||
− | $hTxt.Text = $sInvito | + | If Trim$($hTbox.Text) = "" Then |
+ | $hTxt.Text = $sInvito | ||
+ | Else | ||
+ | $hTxt.Text = "" | ||
+ | Endif | ||
End | End | ||
− | + | Assegna semplicemente il testo di invito alla proprietà testo della ''Label'' solo quando non c'è testo nella ''TextBox''. | |
Continuiamo: | Continuiamo: | ||
Private Function Text_Read() As String | Private Function Text_Read() As String | ||
− | Return $ | + | Return $hTbox.Text |
End | End | ||
Private Sub Text_Write(Value As String) | Private Sub Text_Write(Value As String) | ||
− | + | $hTbox.Text = Value | |
− | $hTbox.Text = | ||
End | End | ||
− | + | Assegnamo al nostro controllo il testo della ''TextBox''. | |
+ | |||
Infine: | Infine: | ||
Riga 160: | Riga 167: | ||
Creiamo il nostro metodo con tanto di spiegazione per la guida. | Creiamo il nostro metodo con tanto di spiegazione per la guida. | ||
− | Abbiamo finito, a questo punto, se tutti i passaggi sono stati eseguiti correttamente, nella ''ToolBox'' dovrebbe esserci il componente ''InvBox''. | + | Abbiamo finito, a questo punto, se tutti i passaggi sono stati eseguiti correttamente, nella ''ToolBox'', scheda ''Form'' dovrebbe esserci il componente ''InvBox''. |
Se non appare provate a dare un ''Compila tutto'' dal menu ''Progetto'', un click sul pulsante ''Ricarica'' o estrema ratio provate a riavviare. | Se non appare provate a dare un ''Compila tutto'' dal menu ''Progetto'', un click sul pulsante ''Ricarica'' o estrema ratio provate a riavviare. | ||
− | Per verificare se il nostro controllo funziona a dovere potete usare tranquillamente la ''FMain'' del componente senza che questi ne abbia a patire, dalla ToolBox della ''FMain.form'' facciamo due volte doppio click sul controllo ''InvBox'' per disegnare due ''InvBox'' sulla finestra, posizioniamo convenientemente i due controlli nella finestra, evidenziamo un controllo alla volta per scrivere nella proprietà ''Invito'' rispettivamente ''Digita qui il nome'' e ''Digita qui il cognome'', aggiungiamo un ''Button'' con scritto nella proprietà Text “''Cancella''”. | + | Per verificare se il nostro controllo funziona a dovere potete usare tranquillamente la ''FMain'' del componente senza che questi ne abbia a patire, dalla ToolBox della ''FMain.form'' facciamo due volte doppio click sul controllo ''InvBox'' per disegnare due ''InvBox'' sulla finestra, posizioniamo convenientemente i due controlli nella finestra, evidenziamo un controllo alla volta per scrivere nella proprietà ''Invito'' rispettivamente ''Digita qui il nome'' e ''Digita qui il cognome'', aggiungiamo un ''Button'' con scritto nella proprietà Text “''Leggi''”, aggiungiamo un secondo ''Button'' con scritto nella proprietà Text “''Cancella''”. |
All'interno della ''FMain.class'' scriviamo il seguente codice: | All'interno della ''FMain.class'' scriviamo il seguente codice: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Public Sub Form_Open() | Public Sub Form_Open() | ||
<Font Color=gray>' ''Si può impostare/cambiare l'invito a runtime'' | <Font Color=gray>' ''Si può impostare/cambiare l'invito a runtime'' | ||
Riga 182: | Riga 182: | ||
<Font Color=gray>' ''Si può utilizzare l'eveto Change.''</font> | <Font Color=gray>' ''Si può utilizzare l'eveto Change.''</font> | ||
Print "Il testo di InvBox1 è cambiato" | Print "Il testo di InvBox1 è cambiato" | ||
+ | End | ||
+ | |||
+ | Public Sub InvBox2_Change() | ||
+ | <Font Color=gray>' ''Si può utilizzare l'evento Change.''</font> | ||
+ | Print "Il testo di InvBox2 è cambiato" | ||
+ | End | ||
+ | |||
+ | Public Sub Button1_Click() | ||
+ | <Font Color=gray>' ''Legge.''</font> | ||
+ | Print InvBox1.Text;; InvBox2.Text | ||
+ | InvBox1.SetFocus() | ||
+ | End | ||
+ | |||
+ | Public Sub Button2_Click() | ||
+ | <Font Color=gray>' ''Azzerando o cancellando i dati'' | ||
+ | ' ''riappariranno gli inviti.''</font> | ||
+ | InvBox1.Text = "" | ||
+ | InvBox2.Clear | ||
+ | InvBox1.SetFocus() | ||
End | End | ||
Se funziona tutto, complimenti avete portato a buon fine il componente. | Se funziona tutto, complimenti avete portato a buon fine il componente. |
Versione attuale delle 13:06, 23 apr 2016
(Autore del Componente e del testo: Gianluigi])
Il componente che andremo a creare è una TextBox con invito, l'uso di questo controllo ci permetterà di evitare le Label di spiegazione.
L'idea è questa; sfruttando la trasparenza della TextBox inseriremo sotto di essa una Label con backgroung (fondo) bianco e foreground (scritta) grigio che riporterà per l'appunto una scritta di invito che apparirà come se fosse della TextBox stessa.
Quando cambieremo i dati nella TextBox, sfruttando l'evento Change della stessa, faremo sparire o apparire la scritta di invito in base alla necessità.
Prima di cimentarvi in qualcosa che potrebbe non funzionare si consiglia di fare questa semplice prova.
Apriamo un nuovo progetto grafico QT application e diamogli un nome qualunque del tipo PoiTiCancello.
Disegnate sulla FMain.form una Label abbastanza lunga e sopra a coprirla abbondantemente disegnate una TextBox.
Poi fate doppio click sulla maschera per passare alla FMain.class e scrivete questo codice:
Public Sub Form_Open() TextBox1.Background = Color.Transparent Label1.Background = Color.TextBackground Label1.Text = "Se mi vedi puoi proseguire" End
Avviate (F5) e se riuscite a leggere la scritta su sfondo bianco potete proseguire con la prova altrimenti dovete impostare il vostro sistema in modo che supporti la trasparenza oppure dovete desistere
Esiste il software QT Configuration sicuramente per le QT4 ma credo ci sia qualcosa anche per QT5, ad esempio per Ubuntu c'è nel Software Center Impostazioni QT che se configurato su Cleanlooks o Plastique funziona benissimo per tante cose, non solo la trasparenza.
Nota: Occorre sempre ragionare prima di usare oggetti particolari che hanno bisogno di settaggi ad hoc.
Pensiamo a chi lo dovrà usare e se sarà in grado di utilizzarlo.
Quindi dopo aver letto quanto scritto da Milio sul componente, apriamo un nuovo progetto di Gambas3 clicchiamo su QT application e poi su Seguente, scegliamo quindi dove mettere il nostro progetto e poi diamogli il nome InvBox e come titolo TextBox con invito.
Clicchiamo sul menu Progetto>Proprietà... si apre la finestra Proprietà dove in Project type agendo sugli spin sceglieremo la voce Componente.
Apparirà sull'elenco di sinistra una nuova voce Information scegliamola cliccandoci sopra, nella finestra che appare scegliamo la voce Sperimentale per Progress, scegliamo NO per This component is idden e spuntiamo la casella Gestione grafica della form, quindi diamo OK.
Nella parte sinistra della finestra in area progetto cliccate tasto destro sulla voce Sorgenti e dal menu contestuale scegliete Nuovo>Classe...
Si apre la finestra Nuovo file alla voce classe cambiatene il nome in InvBox, spuntate Esportato e date 'OK.
Se vi siete dimenticati di spuntare Esportato poco male scrivete Export appena sotto ' Gambas class file.
Il componente che stiamo per creare è un controllo pertanto dovrà ereditare da UserControl quindi appena sotto Export scriviamo Inherits UserControl.
Affinché Gambas comprenda cosa vogliamo ottenere occorre che glielo si indichi attraverso varie cose, iniziamo dalle costanti pubbliche.
Tutte sono utili ma nessuna è indispensabile la principale è la costante delle proprietà. Stavo per scrivere che la costante delle proprietà è indispensabile, in realtà essa lo è solo se vogliamo mostrare all'utente il nostro controllo alla stregua di tutti gli altri.
Come avete già letto nella wiki tutto quello che viene indicato in questa costante ve lo ritroverete nella sezione delle proprietà degli widget (controlli) nella scheda .form, l'area disegno dei form.
Noi per il nostro widget abbiamo bisogno di aggiungere la proprietà Invito quindi scriviamo appena sotto a Inherits UserControl:
Public Const _Properties As String = "*,Invito"
L'asterisco dice a Gambas che il nostro componente mostra tutte le proprietà di UserControl e in più gli dice di aggiungere la proprietà Invito. Badate bene UserControl non vuol dire TextBox che se voi volete dal vostro componente esattamente tutte le proprietà di una TextBox con in più la proprietà Invito dovrete digitare tutte le proprietà che distinguono la TextBox rispetto al controllo base.
Aggiungiamo:
Public Const _DefaultSize As String = "24,4"
Sono le misure del controllo, attenzione anche qui perché queste misure sono particolari esattamente otto pixel cadauna, come se disegnaste a mano nella IDE, vale a dire che di default il vostro componente misurerà 192x32 pixel e così si disegnerà sulla finestra facendogli doppio click sopra dalla ToolBox.
Public Const _Similar As String = "TextBox"
Scrivendo questo dite a Gambas che il vostro componente è simile a una TextBox.
Public Const _DefaultEvent As String = "Change"
Qui diciamo a Gambas che creeremo, come per la TextBox normale, l'evento Change e che questo è l'evento che si scriverà automaticamente nella scheda codice (es. FMain.class) facendoci sopra doppio click.
Se aggiungiamo
Public Const _DrawWith As String = "TextBox"
il nostro componente si disegnerà sul form esattamente come una TextBox altrimenti potrete dargli un vostro stile con tanto di icona.
Nota: Il nostro componente sarà visto dall' utilizzatore del programma come una normale casella di testo, qui si parla di come lo vede il programmatore nella IDE.
Se desiderate riunire tutti i vostri componenti in una scheda a se stante, potete aggiungere:
Public Const _Group As String = "Componenti"
o qualunque nome vi aggrada.
In questo caso non fatelo, così il nostro componente verrà caricato insieme agli altri controlli grafici classici di base nella scheda Form.
Ora, a seguire, diremo a Gambas quali oggetti abbiamo intenzione di usare per costruire il nostro componente, come detto useremo una TextBox e una Label ma non possiamo usare la Label come contenitore della TextBox o viceversa infatti come potete ben vedere dalla scheda Container nessun controllo può essere usato come contenitore. Il più comodo contenitore è senz'altro Panel e infatti useremo questo per il nostro controllo.
Attenzione noi qui possiamo elencare i nostri attrezzi nell'ordine che vogliamo ma poi nel costruttore (_new) occorrerà fare attenzione all'ordine di disegno in quanto il primo rimane sotto al secondo che a sua volta rimane sotto il terzo e così via.
Scriviamo quindi:
Private $hTbox As TextBox Private $hTxt As Label Private $hPanel As Panel
A seguire andiamo a dichiarare le proprietà sia quelle che dovranno apparire nella IDE che quelle che ci servono solo nel codice, ad esempio UserControl non ha una proprietà Text e normalmente questa proprietà una TextBox la mostra nella IDE, ma non avrebbe senso inserire una frase di partenza nella nostra InvBox essendoci già l'invito.
Completiamo pertanto così la parte delle dichiarazioni:
'' Mostra in InvBox la frase di invito. Property Invito As String Private $sInvito As String '' Mostra la frase digitata. Property Text As String '' Viene invocato ad ogni cambiamento nel testo. Event Change
Nota: I commenti in doppio apice verranno visti nella guida in linea e negli aiuti durante la digitazione.
Scriviamo il costruttore della nostra classe:
Public Sub _new() $hPanel = New Panel(Me) $htxt = New Label($hPanel) $hTbox = New TextBox($hPanel) As "Tbox" $hPanel.Arrangement = Arrange.Fill $hTbox.Background = Color.Transparent $hTxt.Background = Color.TextBackground $hTxt.Foreground = Color.RGB(150, 150, 150) $hTxt.Padding = 5 Me.Proxy = $hTbox End
Con questo noi abbiamo detto a Gambas che il nostro componente è racchiuso in un Panel, con arrangement a fill egli espande completamente alle sue misure ciò che contiene.
Contiene appunto la Label e la TextBox a quest'ultima assegniamo gli eventi con “Tbox”
Come detto diamo la trasparenza alla TextBox, lo sfondo TextBackground alla Label e sempre alla Label il colore grigio per il testo di invito.
Con il padding alla label sincronizziamo i testi di entrambi i controlli.
Con Proxy passiamo al nostro controllo le proprietà e gli eventi base di UserControl, potete vederne la lista nella guida in linea facendo F2 sulla parola all'interno della IDE.
Continuiamo:
Public Sub Tbox_Change() If Trim$($hTbox.Text) = "" Then $hTxt.Text = $sInvito Else $hTxt.Text = "" Endif Raise Change End
Utilizziamo l'evento interno proprio della TextBox per mostrare o nascondere il testo di invito e per propagare con Raise l'evento Change al nostro componente.
Continuiamo:
Private Function Invito_Read() As String Return $sInvito End Private Sub Invito_Write(Value As String) $sInvito = Value If Trim$($hTbox.Text) = "" Then $hTxt.Text = $sInvito Else $hTxt.Text = "" Endif End
Assegna semplicemente il testo di invito alla proprietà testo della Label solo quando non c'è testo nella TextBox.
Continuiamo:
Private Function Text_Read() As String Return $hTbox.Text End Private Sub Text_Write(Value As String) $hTbox.Text = Value End
Assegnamo al nostro controllo il testo della TextBox.
Infine:
'' Pulisce InvBox dai dati presenti. Public Sub Clear() $hTbox.Clear End
Creiamo il nostro metodo con tanto di spiegazione per la guida.
Abbiamo finito, a questo punto, se tutti i passaggi sono stati eseguiti correttamente, nella ToolBox, scheda Form dovrebbe esserci il componente InvBox. Se non appare provate a dare un Compila tutto dal menu Progetto, un click sul pulsante Ricarica o estrema ratio provate a riavviare.
Per verificare se il nostro controllo funziona a dovere potete usare tranquillamente la FMain del componente senza che questi ne abbia a patire, dalla ToolBox della FMain.form facciamo due volte doppio click sul controllo InvBox per disegnare due InvBox sulla finestra, posizioniamo convenientemente i due controlli nella finestra, evidenziamo un controllo alla volta per scrivere nella proprietà Invito rispettivamente Digita qui il nome e Digita qui il cognome, aggiungiamo un Button con scritto nella proprietà Text “Leggi”, aggiungiamo un secondo Button con scritto nella proprietà Text “Cancella”.
All'interno della FMain.class scriviamo il seguente codice:
Public Sub Form_Open() ' Si può impostare/cambiare l'invito a runtime ' attraverso la proprietà invito. InvBox1.Invito = "Nuovo invito..." End Public Sub InvBox1_Change() ' Si può utilizzare l'eveto Change. Print "Il testo di InvBox1 è cambiato" End Public Sub InvBox2_Change() ' Si può utilizzare l'evento Change. Print "Il testo di InvBox2 è cambiato" End Public Sub Button1_Click() ' Legge. Print InvBox1.Text;; InvBox2.Text InvBox1.SetFocus() End Public Sub Button2_Click() ' Azzerando o cancellando i dati ' riappariranno gli inviti. InvBox1.Text = "" InvBox2.Clear InvBox1.SetFocus() End
Se funziona tutto, complimenti avete portato a buon fine il componente.
Se si desidera per il nostro componente una grafica particolare allora disegniamo una icona massimo di 32x32 px. nominiamola con lo stesso nome del componente tutto minuscolo (invbox.png) e inseriamola nella cartella creata appositamente e nominata control che poi andremo a inserire a sua volta nella cartella .hidden del progetto InvBox.
Si consiglia di fare queste cose al di fuori della IDE di Gambas, è più agevole.
Adesso che abbiamo un componente funzionante vediamo un modo semplice per incorporarlo nei nostri progetti, anche in questo caso è più facile agire al di fuori della IDE:
Creiamo un nuovo progetto QT e nominiamolo ProvaComponente chiudiamolo e apriamo le cartelle sia quella di InvBox che quella di ProvaComponente e diamo ad entrambe la possibilità di mostrare i file nascosti pertanto:
- se desideriamo usare solo il componente senza fronzoli ci basta copiare il file InvBox.class (quello con la tazzina di caffè) dalla cartella .src e incollarlo nella cartella .src di ProvaComponente quindi dopo aver chiuso le cartelle avviare il nostro nuovo progetto e dare Ctrt+F (Progetto>Compila tutto).
- se invece desideriamo importare anche la grafica occorre copiare da InvBox cartella .hidden e incollare in ProvaComponente cartella .hidden anche la cartella control in questo caso è facile che occorra oltre a compilare tutto, anche ricaricare la grafica attraverso il controllo Ricarica.
Ora potrete usufruire nel vostro nuovo progetto anche del nuovo controllo, il componente InvBox.