Ultimo post sull'argomento, giuro! :o)
Se qualcuno dopo di me fosse interessato, la soluzione di giulio non permette di creare dinamicamente quante etichette si desidera, la mia modifica per poterlo fare e' la seguente:
PUBLIC SUB Form_Open()
DIM tips AS NEW Object[]
DIM i, i_tips, tips_y AS Integer
i_tips = 5
FOR i = 0 TO i_tips
tips.Add(Label, i)
tips[i] = NEW Label(ME)
WITH tips[i]
.X = 10
.Y = tips_y
.width = 100
.height = 20
.text = "Abc " & i
END WITH
tips_y += 30
NEXT
END
dove, ovviamente i_tips puo' essere impostato a piacere in fase di esecuzione del programma in modo da ottenere etichette a piacere.
Saluti a tutti e tante grazie (a giulio in particolare per avermi indirizzato verso la soluzione!).
Andrea
...bensì uno solo ogni qual volta io premo un tasto; ma sempre mediante l'uso di un array che mi consenta di distinguerli per numero ai fini di una successiva gestione.
Allora, siccome sul forum vige la norma "Sperimenta. Trova la soluzione; e solo poi domanda come si trova la soluzione già trovata" :evil: .....nell'attesa di una risposta, ho dovuto cercare di rispondermi da me :rolleyes: .
Ho dunque ottenuto l'effetto che desideravo, ma senza array. Ho fatto così:
' Gambas class file
s As Integer
i As Integer
Public Sub Button1_Click() ' Crea UNA SOLA Label ogni qualvolta viene premuto Button1
Dim lab As Label
i = i + 1
' crea la Label e aggiunge al suo nome anche il numero contenuto nella variabile “ i “.
lab = New Label(Me) As "lab" & i
With lab
.X = 20
.Y = s
.Width = 50
.Height = 20
.tooltip = "Sono la Label " & i
' imposta il testo all'interno della Label.
.Text = "Label" & i
End With
s = s + 30
Object.Attach(lab, Me, "Evento") ' associa l'oggetto Label alla definizione "Evento"
End
Public Sub Evento_MouseDown() ' cliccando su una Label, fra quelle create, essa viene eliminata.
Dim Obj As Object = Last
Dim a As String
a = Obj.name
Obj.delete ' elimina la Label riportata da Last
' Scrive quale Label è stata eliminata fra quelle precedentemente create.
' La variabile " a " indica il nome riportato da Obj.name.
Print "Eliminata " & a
End
Sono tornato sulla questione da me posta.
Ricapitolando: la mia intenzione è di ottenere più oggetti del medesimo tipo, però creandone uno solo ogni qual volta io premo un tasto, e sempre mediante l'uso a livello di codice di un array che mi consenta di distinguerli per numero ai fini di una successiva gestione.
Nella mia risposta del 12 Luglio 2011, 00:08:11, ho inserito un listato, con il quale ho ottenuto un risultato finale funzionante in modo eguale al mio scopo ultimo (la gestione degli oggetti creati), però in questo caso senza uso di array. Avevo escogitato lo stratagemma di un falso array, legato al nome di ogni oggetto creato; nome che veniva così distinto da quelli attribuiti agli altri oggetti del medesimo tipo creati. Infatti, successivamente potevo eliminare l'oggetto operando sul suo nome.
Ora - mi sembra - di aver trovato la soluzione (che mi pare più semplice di quanto non avessi previsto) di creare più oggetti del medesimo tipo, e sempre uno solo ad ogni click su tasto, ma con l'uso di array (esperimento compiuto in Gambas 3):
' Gambas class file
Private Lblarray[5] As Label ' pongo il limite di prova massimo a 5 oggetti ("array di 5 elementi")
Private a As Integer
Private b As Integer
Public Sub Button1_Click() ' Crea UNA SOLA Label ogni qualvolta viene premuto Button1
Dim c, d As Integer
b += 50
' crea la Label e la distingue dalle altre eventuali con un numero contenuto nella variabile “ a “,
' (ma questa volta non in aggiunta alla sua denominazione).
Lblarray[a] = New Label(Me)
Lblarray[a].Border = Border.Raised ' definisco le caratteristiche della label
Lblarray[a].W = 100 ' in modo tale da posizionare le varie Label ottenute
Lblarray[a].H = 20 ' in luoghi diversi sul Form
Lblarray[a].X = b '
Lblarray[a].Y = b '
Print Lblarray[a].ID ' per prova trovo l'ID della Label appena creata e distinta con la variabile "a" dell'array.
' Per ulteriore prova intendo distruggere una Label precedentemente creata
' indicandone (questa è la prova effettiva) il numero assegnatole con la variabile " a ".
If a = 4 Then
d = InputBox("Elimina una label (il numero deve essere compreso fra 0 e 4)")
Print Lblarray[d].ID ' ri-ottengo per riprova l'Id della Label scelta in InputBox
Lblarray[d].delete ' elimina la Label segnata dalla variabile dell'array scelta in InputBox
Endif
a = a + 1 ' incremento la variabile relativa alla cella dell'array di indice 0
End
Ci sono ?
Ciao a tutti,
ho ripreso questa discussione, perchè mi è tornato utile questo esempio:
Ultimo post sull'argomento, giuro! :o)
Se qualcuno dopo di me fosse interessato, la soluzione di giulio non permette di creare dinamicamente quante etichette si desidera, la mia modifica per poterlo fare e' la seguente:
PUBLIC SUB Form_Open()
DIM tips AS NEW Object[]
DIM i, i_tips, tips_y AS Integer
i_tips = 5
FOR i = 0 TO i_tips
tips.Add(Label, i)
tips[i] = NEW Label(ME)
WITH tips[i]
.X = 10
.Y = tips_y
.width = 100
.height = 20
.text = "Abc " & i
END WITH
tips_y += 30
NEXT
END
dove, ovviamente i_tips puo' essere impostato a piacere in fase di esecuzione del programma in modo da ottenere etichette a piacere.
Saluti a tutti e tante grazie (a giulio in particolare per avermi indirizzato verso la soluzione!).
Andrea
è fin qui tutto ok, quello che non riesco a fare è utilizzare gli eventi degli oggetti creati (per es.: Oggetto_Click, Oggetto_GotFocus, ecc...).
Facendo varie ricerche sul Forum penso di aver capito che va usata la sintassi
Object.Attach(NomeOggetto, Contenitore, "TipoOggetto")
ma non ho capito come applicarla all'esempio soprariportato.
è fin qui tutto ok, quello che non riesco a fare è utilizzare gli eventi degli oggetti creati (per es.: Oggetto_Click, Oggetto_GotFocus, ecc...).
Facendo varie ricerche sul Forum penso di aver capito che va usata la sintassi
Object.Attach(NomeOggetto, Contenitore, "TipoOggetto")
ma non ho capito come applicarla all'esempio sopra riportato.
In vero puoi anche usare quel che c'è già, ossia (dato che parlavi di evento _click, più coerentemente ho cambiato la Label in Button):
Public Sub Form_Open()
Dim tips As New Object[]
Dim i, i_tips, tips_y As Integer
i_tips = 2
For i = 0 To i_tips
tips.Add(Button)
tips[i] = New Button(Me) As "tips" & i
With tips[i]
.X = 10
.Y = tips_y
.width = 100
.height = 40
.text = "Abc " & i
End With
tips_y += 30
Next
End
Public Sub tips0_Click()
Print "alibaba 0"
End
Public Sub tips1_Click()
Print "alibaba 1"
End
Public Sub tips2_Click()
Print "alibaba 2"
End
Puoi anche catturare tutti gli eventi di tutti i pulsanti con un solo gestore:
...
tips[i] = New Button(Me) As "tips"
tips[i].Name = "tips" & i
...
...
Public Sub tips0_Click()
Select Case Last.Name
Case "tips0"
Print "alibaba 0"
Case "tips1"
Print "alibaba 1"
...
End Select
End
Puoi anche catturare tutti gli eventi di tutti i pulsanti con un solo gestore:
E' vero. Mi permetto di correggere il codice eliminando solo un carattere rimasto lì imbambolato come un asino in mezzo ai suoni:
Public Sub tips_Click() ' era rimasto l'asino: tips0
....etc...etc
E se il numero non può essere stabilito a priori?
...ed allora è ancora più semplice: ;D
Private i As Integer
Private tips As New Object[]
Private tips_y As Integer
Public Sub Form_Open()
End
Public Sub Button1_Click() ' Ogni volta che si preme sul Button1, si crea ed aggiunge un Button nell'array
tips.Add(Button)
tips[i] = New Button(Me) As "tips"
With tips[i]
.X = 10
.Y = tips_y
.width = 100
.height = 40
.text = "Tasto n. " & i
End With
tips_y += 40
i = i + 1
End
Public Sub tips_Click()
' Ritorna la posizione nell'array del "Button" che abbiamo premuto:
Print "alibaba " & tips.Find(Last)
End
Questo metodo: var_array.Find(Last) ovviamente può essere applicato anche nei precedenti casi.
Esempio:
Private ar As New Button[]
Public Sub Form_Open()
Dim bt As Button
Dim j As Byte
For j = 0 To 9
bt = New Button(Me) As "bt"
ar.Add(bt)
Next
For j = 0 To 9
With ar[j]
.X = 10
.Y = 1 + (30 * j)
.W = 60
.H = 30
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & ar.Find(Last)
End
La sparo: doppio ciclo for-next nidificato usando il valore del ciclo più esterno e moltiplicandolo per un altro valore base così da ottenere i pulsanti perfettamente allineati?
Ma un asino come me è incapace di doppi salti mortali carpiati con avvitamento. Pertanto propongo nuovamente un goffo salto di pancia: ;D
Private ar As New Button[]
Public Sub Form_Open()
Dim bt As Button
Dim j As Byte
For j = 0 To 39
bt = New Button(Me) As "bt"
ar.Add(bt)
Next
For j = 0 To 39
With ar[j]
.X = (10 * (j \ 10)) * 8
.Y = (j - ((j \ 10) * 10)) * 30
.W = 60
.H = 30
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & ar.Find(Last)
End
Non è necessario tenersi in memoria un array con gli oggetti creati, perchè lo fà già la form quando li crei (e li associ come parent alla form stessa).
Per poter identificare l'oggetto hai più possibilità, dipendentemente dalla situazione in cui ti trovi.
Allora, adattando il mio codice all'interessante suggerimento di md9327, verrebbe così:
Private bt As Button
Public Sub Form_Open()
Dim j As Byte
For j = 0 To 39
bt = New Button(Me) As "bt"
Next
For j = 0 To 39
With Me.Children[j]
.X = (10 * (j \ 10)) * 8
.Y = (j - ((j \ 10) * 10)) * 30
.W = 60
.H = 30
.Name = Str(j)
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & Last.Name
End
Grazie vuott, puntuale come sempre. :D
...ma con il suggerimento di md9327 possiamo abbreviare ancora di più il codice:
Private bt As Button
Public Sub Form_Open()
Dim j As Byte
For j = 0 To 39
bt = New Button(Me) As "bt"
With Me.Children[j]
.X = (10 * (j \ 10)) * 8
.Y = (j - ((j \ 10) * 10)) * 30
.W = 60
.H = 30
.Name = Str(j)
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & Last.Name
End
Public Sub Form_Open()
Dim bt As Button
Dim j As Byte
For j = 0 To 39
With bt = New Button(Me) As "bt"
.X = (10 * (j \ 10)) * 8
.Y = (j - ((j \ 10) * 10)) * 30
.W = 60
.H = 30
.Name = Str(j)
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & Last.Name
End
Meglio così... ;D
Inoltre vi ricordo che esistono gli oggetti VBox/HBox, che possono posizionare automaticamente i gli oggetti in essi contenuti, rendendo quindi inutile l'utilizzo delle proprietà X/Y/W/H, e quindi non è necessario impostarli a mano perchè ci pensa il manager.
Ok md9327 concetto appreso, grazie della ulteriore spiegazione.
Ora mi capita una cosa "strana", utilizzando sempre il tuo esempio l'ho adattato al mio progetto in questo modo:
Public Sub Form_Open()
Dim bt As Button
Dim j As Byte
For j = 0 To 255
With lb = New Button(Me) As "bt"
.X = 5 + ((64 * (j \ 64)) * 1.56)
.Y = 1 + ((j - ((j \ 64) * 64)) * 25)
.W = 96
.H = 24
.Name = Str(j)
End With
Next
End
Public Sub bt_Click()
Print "Hai premuto il tasto n. " & Last.Name
End
ma il programma si blocca senza indicare nessun errore. Ora mi sorge un dubbio, anzi vi pongo la domanda:
ma c'è un limite al numero di oggetti che si possono creare?
Perchè se porto variabile J al di sotto di 255 tutto riprende a funzionare correttamente.
Il limite credo sia imposto dalla dimensione della memoria.
In realtà, in alcuni casi, ho notato che Gambas soffre se l'applicazione impiega troppa memoria.
Ad ogni modo, il suggerimento sul tipo di variabile usata per il loop è corretto, anche se è la causa del tuo problema, visto che hai 40 oggetti.
Ora è abbastanza tardi, e ho la capa un pò fusa, ma credo dovresti controllare i calcoli che fai sul dimensionamento...
E poi c'è un errore:
With lb = New Button(Me) As "bt"
...
chiami la variabile "lb", invece di "bt"...