Perché ogni widget ha bisogno di un riferimento al suo genitore in un semplice sistema di widget?

8

Sto lavorando su un semplice sistema di widget (finestra singola, dimensione fissa). Ogni widget ottiene il suo genitore (cioè il widget che lo contiene) passato nel suo costruttore - tranne che per il widget di root, che ho chiamato Screen .

Ho qualche dubbio se questo approccio ha un senso. L'ho fatto perché la maggior parte dei sistemi di widget che ho usato prima lo facevano (Qt, GTK, ...), ma ho capito che questi sono un po 'più complessi dei miei:

  • Non ho ridimensionamento della finestra
  • Non ho intenzione di ridimensionare i contenitori in base alle dimensioni dei loro figli
  • Non credo di averne bisogno per la gestione della memoria (sto usando C ++), posso usare invece dei puntatori condivisi (in pratica come funzionerebbe in Java)

C'è qualche ragione per cui un widget avrebbe bisogno di un riferimento al suo genitore?

È un importante refactoring cambiare questo. Quindi prima di andare avanti e implementare contenitori e layout, voglio avere una buona idea se avrò bisogno o meno di quel genitore.

Modifica: Nota che il genitore conosce comunque tutti i suoi figli, mi chiedo solo se anche i bambini devono conoscere il genitore.

    
posta futlib 01.03.2013 - 12:38
fonte

3 risposte

5

Come hai sottolineato, il bambino stesso raramente ha bisogno di accedere al genitore, a patto che il genitore faccia tutto il lavoro e tenga traccia dei suoi figli. Tuttavia, il classico getParent è molto utile quando usi il framework dall'esterno.

Scenario

Una semplice operazione che può causare problemi è la seguente: dati due widget concreti che si trovano da qualche parte nell'albero di widget complessivo e un caso d'uso che richiede di scambiarli, come funziona lo scambio?

Opzione 1: dai ai bambini

Dì al widget figlio a swap(withOtherChild) . Ma lo swapping comporta in qualche modo l'aggiornamento della struttura dei dati dei figli dei genitori. Come tuo figlio non conosce il suo genitore, come lo ottieni?

Opzione 2: informa i genitori

Dì al genitore di un bambino di rimuoverlo e aggiungere l'altro. Oh aspetta, lo stesso problema. Hai solo gli oggetti figli e non c'è getParent su quelli.

Opzione 3: lavoro Grunt

Come opzione finale, puoi attraversare l'intero albero dei widget per trovare un genitore con hasChild(x) e uno con hasChild(y) e poi tornare all'opzione 2.

Soluzione

Devi mantenere il genitore se vuoi costruire alberi di grandi dimensioni ed eseguire operazioni che richiedono lo spostamento della posizione di un widget nell'albero. Se gli alberi dei widget sono molto piccoli, o hanno solo una profondità molto piccola, ma gli accessor hasChild veloci, allora l'opzione 3 potrebbe essere accettabile per te e tu potresti omettere il riferimento principale.

Riferimenti in Datastructures in generale

Quello che stai progettando di fare qui è costruire un datastructure per un albero. Prendiamo in considerazione una semplificazione e per il gusto dell'argomento supponiamo che ogni widget possa avere un solo figlio. Il risultato, ovviamente, è un elenco e la tua domanda ora diventa "dovrei avere un elenco con collegamento singolo o doppio?".

E proprio come le liste, non c'è una risposta definitiva, ma solo pro e contro. I professionisti evidenti per il single-linked (cioè, nessun riferimento genitore) sono a) più facili da implementare eb) meno memoria. Ma i contro includono: a) alcune operazioni diventano lente in quanto devono attraversare la struttura eb) non avere un facile accesso a tali operazioni può significare che la struttura dati è ingombrante da usare, e c) usa più memoria.

D'altro canto, la variante double-linked, cioè con riferimento al genitore, rovescia praticamente questi pro e contro.

In termini di una libreria / struttura della GUI, tuttavia, i limiti di memoria non sono di solito un problema che vieta i puntatori dei genitori. Se lo escludete e rendetevi conto che si tratta di una libreria / framework, e quindi è preferibile che sia difficile da implementare, ma facile da usare, in pratica si escludono i pro di un approccio single-linked.

Non sono a conoscenza delle peculiarità del tuo progetto, quindi voglio astenermi dal dirti di mantenere il riferimento del genitore, poiché alcuni dei miei ragionamenti di cui sopra potrebbero non essere applicabili nel tuo caso. In generale, tuttavia, considero che i riferimenti dei genitori in una infrastruttura di widget siano utili per i motivi sopra indicati.

    
risposta data 01.03.2013 - 13:29
fonte
2

Nella maggior parte di questi casi c'è una certa comunicazione tra genitori e figli in caso di eventi, segnali o cambiamenti di stato (o semplicemente per distruggere i bambini quando necessario). Ad esempio, un riquadro di raggruppamento può gestire i pulsanti di opzione contenuti per garantire che solo uno di essi sia "attivo" in un dato momento.

Potresti o meno progettare di avere funzionalità di questo tipo. Personalmente dubito che un sistema di widget senza esso vale il tempo dato che non offrirebbe molto. Ma poi userò semplicemente una delle soluzioni esistenti comunque.

    
risposta data 01.03.2013 - 12:49
fonte
1

Direi che, quando i bambini conoscono i loro genitori, un widget e tutti i suoi antenati formano una catena di responsabilità . Un tipico esempio è un evento del mouse ricevuto da un widget: il widget può consumare l'evento (e reagire di conseguenza) oppure passare l'evento al suo genitore, che può consumare o passare al suo genitore, ecc ...

Nel caso di Qt, ogni costruttore riceve il suo genitore dal costruttore, e questo indica che il widget è di proprietà del genitore. In particolare, la cancellazione del genitore attiva la cancellazione del widget.

    
risposta data 01.03.2013 - 14:38
fonte

Leggi altre domande sui tag