Autore Topic: [RISOLTO]form child  (Letto 3644 volte)

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
[RISOLTO]form child
« il: 11 Ottobre 2009, 01:13:49 »
salve raga

ho creato un form main, e ora sto creando altri form che si dovrebbero comportare come child, quando riduco ad icona il main anche tutti i child devono seguirlo.

mi date una mano?

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #1 il: 12 Ottobre 2009, 11:57:47 »
Un'ipotesi è quella di salvare nella form generale tutti i collegamenti alle form figlie, nel senso che basta che crei un oggetto array (Object[]) a cui aggiungi mano mano le altre form. Questo oggetto potrebbe essere una proprietà della form stessa.
Nell'evento iconize della form padre, ti fai un loop dell'array, ed esegui la stessa cosa per tutti gli oggetti contenuti in esso.
Idem con patate per altri eventi o funzionalità che vuoi inserire.
E' ovvio che devi gestire anche la chiusura di una form figlia, ovvero comunicare alla master che lei stà morendo, e di attivare tutte le procedure del caso, compreso un'eventuale divieto di chiusura, utile nel caso tu voglia completare delle validazioni.

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #2 il: 15 Ottobre 2009, 13:11:29 »
in teoria riesco a capire il tuo consiglio, ma quando vado per metterlo in pratica mi incarto.

mi faresti un esempio solo della prima parte, e cioè creare un array e inserire una form figlia?

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #3 il: 15 Ottobre 2009, 15:02:10 »
Nella classe Form master, devi dichiare e aggiungere una proprietà alla stessa classe:
Codice: [Seleziona]

PRIVATE $forms AS NEW Object[]

L'istruzione deve essere interna al file di classe, ma esterna da qualsiasi metodo o funzione. In teoria devi collocarla ad inizio file classe.
Quindi dichiari un tuo metodo:
Codice: [Seleziona]

PUBLIC SUB ChildClosing(child AS Object)
  DIM n AS Integer
  FOR n = 0 TO $forms.Max
    IF ($forms[n] = child) THEN
      $forms.Remove(n)
      BREAK
    END IF
  NEXT
END

il metodo sarà poi utilizzato dalle form figlie per comunicare alla master la loro chiusura.

Quando apri una nuova Form figlia, ad esempio tramite un pulsante ad-hoc, basta che nel metodo Click() del pulsante, aggiungi queste istruzioni:
Codice: [Seleziona]

PUBLIC SUB Button_Click()
  DIM newForm AS NEW Form()
  $forms.Add(newForm)
  newForm.Show()
END

Ovviamente io ho usato un oggetto Form generico, che può essere sostituito da una tua Form, l'importante è che l'aggiungi all'array $forms.
Nelle Form figlie, dovresti implementare alcune istruzioni, sia nel metodo _new() che nella Close() di ciascuna, in modo da definire nella figlia chi sia il padre, e notificare alla master la chiusura della sua figlia:
Codice: [Seleziona]

PRIVATE $master AS Object

PUBLIC _new(master AS Object)
  $master = master
END

PUBLIC Form_Close()
  $master.ChildClosing(ME)    
END

Come vedi, nelle figlie è necessario utilizzare il costruttore nascosto di ogni oggetto, o classe, gestito da Gambas: _new().
Questo per poter definire un nuovo parametro "master", con cui gli viene passato il riferimento alla Form master, e che viene salvato nella proprietà $master della form. La proprietà $master sarà poi utilizzata per chiamare un metodo della form master, appunto ChildClosing(), con cui notificare della sua chiusura la form master.

A parte i giri di parole, che spero siano state chiare, tu puoi far interagire le varie Form in modo anche più complesso; ad esempio potresti impedire la chiusura delle form figlie, bloccando l'evento tramite il metodo ChildClosing(), oppure creare un link di comunicazione tra le finestre a prescidere dalla gerarchia padre/figlia, e via dicendo...

Spero sia stato tutto chiaro, in caso contrario, fammi sapere.

Bye

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #4 il: 15 Ottobre 2009, 18:18:14 »
md sei grande
se riusciro a coronare il mio sogno ( formattare windows )  lo dovro anche a te.

grazie

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: form child
« Risposta #5 il: 15 Ottobre 2009, 18:28:15 »
Citazione

desadex ha scritto:
md sei grande
se riusciro a coronare il mio sogno ( formattare windows )  lo dovro anche a te.

grazie


Beh si.....ha la sua età....ma non denigrarlo solo perchè è anziano...poverino...

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #6 il: 15 Ottobre 2009, 21:17:38 »
Roba da matti... ma chi ha lasciato la porta aperta??!!??

Sento uno spiffero...    :freddo:

...
...

 :-P  :-P  :-P  :hammer:  :hammer:  :hammer:  :shit:  :shit:  :shit:  :duro:  :duro:  :giullare:  :giullare:  :giullare:  :ble:  :ble:  :ble:  :ot:  :spam:

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #7 il: 20 Ottobre 2009, 19:51:38 »
anni di visualbasic mi hanno rovinato, o forse perchè non ho mai usato array, ma non riesco ad uscirne.

md ho due form il primo cassa ed il secondo griglia.

mi aiuti a capire come inserirli nell'array?

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #8 il: 21 Ottobre 2009, 11:53:53 »
Forse se spieghi meglio cosa vuoi ottenere, forse riesco a darti una mano.

Se hai compreso la mia precedente spiegazione, non credo sia complicato applicarla a quello che vuoi fare.

Ad ogni modo, descrivi cosa vuoi fare...

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #9 il: 21 Ottobre 2009, 22:56:03 »
ho un form main che si apre a pieno schermo, all'interno apro a misure prestabilite vari form, per ora ne ho 2 , il primo cassa ed il secondo griglia. a progetto ultimato ne dovrebbero essere più di 70.

ma per ora concentriamoci sui due form.

per la chiusura del main si deve chiudere tutto il progetto e mi è bastato mettere quit nel main e funziona.

il problema è che se invece di chiudere il main lo riduco a icona i form cassa e griglia che si trovano aperti restano li.
vorrei che anche loro seguissero il main togliendosi dal desk o meglio ancora farli scomparire con hide (attenzione non voglio chiuderli in quanto perderei i dati), alla riapertura del main dovrebbero tornare al loro posto o con massimize oppure con show.

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #10 il: 22 Ottobre 2009, 11:44:38 »
Allora... due cosine...

Mi sembra di aver rispoto ad un'altra discussione, circa l'utilizzo della classe Workspace; dovresti dargli un'occhiata...

Ad ogni modo, gradirei sapere se la tua applicazione si basa su una Form specifica, o sull'oggetto Application.

Questa cosa è molto importante, in quanto un programma può essere controllato in maniera più efficiente e professionale, se il tutto si basa sulla classe Application.

Nelle librerie di Gambas, esiste una classe, Application, che è statica, ovvero utilizzabile direttamente senza l'uso di creazioni varie. Le librerie Gambas per gtk e kde, hanno incorporata una versione derivata da questa, con alcune proprietà e metodi aggiuntivi.
A parte questo, la classe Application contiene un riferimento alla MainView, ovvero la Form principale dell'applicazione.
Da questa MainView, che può essere una classica Form, possono essere create ulteriori finestre, come è ovvio, e queste si adeguano automaticamente allo stato della MainView.
Un esempio reale è l'ambiente ide di Gambas che, partendo da un Application, crea la sua MainView (la finestra madre, nella sua interezza), che contiene a sua volta le finestre che apre (da menu o da codice).

Spero di spiegarmi al meglio...

Questa logica viene chiamata MDI (multiple document interface).

Se, nel tuo caso, il tuo programma si appoggia su una classica Form (logica SDI, single document interface), e vuoi che le figlie seguano il suo stato, la cosa diventa complicata, in quanto all'applicazione non è stata definita un vista principale. La complicazione consiste nell'implementare una sorta di collegamento comunicativo tra le varie finestre, che viene gestito in particolare da una form specifica. Questo comporta l'aggiunta di un mucchio di codice, e la logica deve controllare bene i protocolli usati nella comunicazione.

Tutto il discorso può essere ovviato dall'uso della logica che ti ho descritto prima, ovverro Application + MainView. Tieni conto che tutto il giochetto viene gestito in maniera trasparente dall'applicazione stessa, per cui ti evita di impiccarti con la scrittura di codice astruso e complicato, oltre che poco manutenibile.

La logica SDI viene usata, di norma, in piccole applicazioni con una singola form, che contiene tutte le caratteristiche del tuo programma. Se il programma prevede di gestire molte più cose, credo sia più logico usare il metodo MDI.

Se non ricordo male, l'uso del sistema SDI era molto di moda con VB, ma solo per le piccole applicazioni. Di solito, in progetti grandi, l'avere finestre svolazzanti e indipendenti, in giro per lo schermo, era cosa molto poco gradita, oltre che faceva perdere il controllo, anche di chi usava il programma.

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #11 il: 24 Ottobre 2009, 20:12:39 »
la storia è questa:
Ho realizzato un programma di gestione con visualbasic che si basa sul principio dell'mdi in quanto fra form, griglie e report ci sono oltre 300 maschere.

ora dopo l'ennesimo problema dei virus con quel sacco di pulci di xp, e dato che, il mio programma è l'ultimo che mi tiene legato a zio bill, ho deciso di cominciare a migrare verso il pinguino.

in pratice dovrei riprodurre quel programma con gambas riscrivendo tutto il codice e nel frattempo cercare anche di migliorarlo.

il progetto si basa su una form di avvio (serve per inserire username e password, dato che è multiutente) la quale dopo i controlli di rito apre il main a pieno schermo.

non conoscendo gambas ho cominciato il progetto creando singolarmente le form e basandomi sulle librerie qt.

dato che sono all'inizio farei ancora in tempo a ripartire da zero ma con il piede giusto.

attualmente sto utilizzando ubuntu ma il progetto una volta finito dovra girare su kde.

nel manuale di gambas ho letto che addirittura si possono creare form una dentro l'altra, ho anche provato a usare il codice ma mi richiede 2 parametri che non riesco a capire di che si tratta.

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #12 il: 27 Ottobre 2009, 13:05:41 »
Tranne che per le Form, ogni controllo grafico ha, per default e obbligatorio, un parametro, ad indicare quale oggetto è il suo parent, ovvero da chi dipende.

Per le form la cosa è diversa, perchè nella libreria è definita come classe a sè stante, quasi una statica.

Però questo non esclude la possibilità di passargli parametri personalizzati, come ad esempio un parent. Il metodo "_new()" è utilizzabile per questa cosa.

Tieni presente che, però, la gestione di questi parametri, non viene effettuata dall'interprete Gambas, perchè non compresi nella propria logica, e quindi questa deve essere implementata da te.

Descrivere qui, in due parole, il concetto e l'uso di una Application è piuttosto complicato. Se puoi perdere qualche ora, ti posso consigliare di scaricarti il mio pgDesigner, e provare a leggerne il codice sorgente.
pgDesigner è costruito sull'oggetto Application, così come ti avevo descritto, che gestisce tutta la parte logica, mentre l'ambiente grafico è a carico dalla MainView, ma sempre sotto il controllo di Application.
Forse troverai il codice un pò incasinato, perchè è stato stravolto per circa 2 anni; nel caso puoi provare a scaricare dal repository la versione 2.0 alpha, che ho piuttosto rivoluzionato e pulito, e a cui stò ancora lavorando.
Se ti interessa, posso consigliarti di capirne la logica iniziale, che parte da un modulo, per l'acquisizione dei parametri di lancio e delle impostazioni di base, poi fà partire una Application, che crea la sua mainview. Da quel punto in poi, è tutta logica di programma. Le form che crea vengono gestite dalll'applicazione, e così via...

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: form child
« Risposta #13 il: 30 Ottobre 2009, 21:09:20 »
md
penso che un esempio dicodice vale + di numerose lezioni.

provo a vedere il tuo programma.
dicevi dei repository canonical per la 2 alpha?

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: form child
« Risposta #14 il: 01 Novembre 2009, 18:39:36 »
Sì, il repository è quello della versione che stò sviluppando.

Ad ogni modo, se leggi la doc ufficiale, per ogni oggetto descritto, derivante da Control, è obbligatorio il passaggio di un parametro, che corrisponde all'oggetto che lo contiene (Container).
Tutto ciò è valido, ad eccezione della classe Form.
Però la cosa è possibile comunque realizzarla per le classi Form, utilizzaando il metodo costruttore "_new()", nel quale puoi definire zero o più parametri a tua scelta, che verranno passati nella creazione dell'oggetto.

Ti faccio un semplice esempio...

Ammettiamo che tu abbia creato un oggetto Form, una bella finestrina vuota, su cui lavorare, inserendo poi gli oggetti che ti servono.
All'inizio della classe (praticamente la parte sorgente della Form), dichiari il metodo costruttore, inserendo alcuni parametri:
Codice: [Seleziona]

PUBLIC SUB _new( parent AS Object, OPTIONAL titolo AS String = "" )
...
END

Il metodo costruttore così creato, permette il passaggio di ulteriori nuovi parametri (la Form, come detto, non ne ha manco uno).
Nell'esempio ho definito un parametro Object, e un parametro opzionale di tipo String.
Se, ammettiamo il caso, tu voglia definire la Form come una finestra figlia di un padre noto (di solito la madre è sicura, il padre no...), quando crei l'oggetto, gli passi il "parent", che corrisponde alla Form padre, o qualsiasi altra cosa che ti serve per la sua gestione.
...Il secondo parametro è, ovviamente, un esempio non utile al nostro discorso...
Quindi, nella creazione della tua Form, ad esempio tramite un pulsante, tu avresti questo codice:
Codice: [Seleziona]

PUBLIC SUB Button_Click()
DIM formFiglia AS NEW TuaForm( ME, "Titolo" )
formFiglia.Show()
END

dove con "ME" identifichi la finestra padre.
La logica è applicabile a qualsiasi oggetto, o classe, che tu definisci nella tua applicazione, indipendentemente se grafico o meno.

Ricorda che, comunque, Gambas esegue in sequenza:
1) il costruttore della classe superiore, ovvero la classe Window con cui è struttura Form, e da cui è derivata;
2) il costruttore della tua form.
Nel caso il costruttore della classe superiore preveda parametri, questi devono essere passati come gli ultimi parametri, durante la costruzione della classe.
Un esempio può essere un oggetto Control, che ha come parametro, appunto, l'oggetto che lo contiene:
Codice: [Seleziona]

PUBLIC SUB _new(parent AS Container) 'costruttore di Control
PUBLIC SUB _new(parent AS Object, title AS String, superParent AS Container) 'costruttore della tua Form


Comunque, io direi che un'occhio al wiki, su cui ho scritto qualcosa in merito, non guasterebbe...

Bye