Newsgroup: it.comp.os.linux.development
Titolo: Gtk Ctree ... ma come funziona???

Hi all, sto scrivendo un piccolo programmino in python utilizzando le
gtk per l'interfaccia.
Sto avendo in particolare dei problemi con un CTree, non riesco a creare
nodi che contengano più figli.
In pratica per sperimentare ho provato ad inserire un elemento settando
il parent a None,in questo:
 nodo=ctree1.insert_node(None,None,("colonna1","colonna2","colonna3"))
i nodi successivi li inserisco assegnandogli come parent "nodo", in
questo modo:
 ctree1.insert_node(nodo,None,("colonna1","colonna2","colonna3"))
In questo modo questi dovrebbero risultare tutti accorpati sotto il
padre creato in precedenza (e dovrebbe apparire l'iconcina che permette
di espandere/comprimere il thread), invece tutti i nodi risultano
indipendenti, come se fossero tutti padri.
Dove sta il mio errore?
-- 
 |\ |       <-> 
http://digilander.libero.it/nemesis2001/
 | \|emesis <->      "War, war never change us..."
 

 nodi che contengano più figli.
Non farlo. Usa un gtk.TreeView e le nuove pygtk (1.99.14) con le gtk2.
In examples/pygtk-demo/demo/treemodel.py trovi un esempio che dovrebbe
chiarirti tutti i dubbi (almeno, a me li ha chiariti in 5 minuti).
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)              [ 
http://digilander.iol.it/ebassi/
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

 chiarirti tutti i dubbi (almeno, a me li ha chiariti in 5 minuti).
Purtroppo in questo modo dovrei installare le gtk2 che penso si
affianchino ma non sostituiscano le gtk1.2 (uso Deb Woody) e vorrei
evitarlo visto che ho qualche problemino di spazio. Inoltre di solito
preferisco installare solo deb ufficiali, e non penso che le nuove pygtk
siano gia disponibili per Woody :-/
Grazie lo stesso.


 penso che le nuove pygtk siano gia disponibili per Woody :-/
Mi pare proprio di si. Ad ogni modo, basta prenderli da Sarge (anche se
effettivamente, python2.2-gtk2 richiede le nuove libc6)...
+++
Dico questo perché usare i CTree e le CList era penoso sotto le gtk1.2,
mentre il TreeView + TreeStore (o ListStore), a fronte di maggiori
difficoltà iniziali, sono molto più potenti e flessibili. E anche perché
ormai, se si vogliono scrivere dei programmi con le GTK, è sconsigliato
usare la versione 1.2.
+++
Per la tua domanda, così risolviamo il problema (e scusa se non ti ho
risposto subito):
Se vuoi inserire dei nodi ad un nodo, devi usare anche l'opzione
`sibling':
root = ctree.insert_node(None, None, "Hello, my name is Root")
node = ctree.insert_node(root, None, "And I'm Child 1")
node = ctree.insert_node(root, node, "And I'm Child 2")
node = ctree.insert_node(root, node, "And I'm Child 3")
node = ctree.insert_node(node, None, "I'm Granchild 1")
Produrrà:
Hello, my name is Root
    +---- And I'm Child 1
    +---- And I'm Child 2
    +---- And I'm Child 3
	+---- I'm Granchild 1
(A meno che non stia prendendo delle cantonate pazzesche: è un po' che
non uso un CTree).
+++
Con un TreeView, invece, la faccenda si fà leggermente più complessa, ma
sicuramente più interessante.
Prima, ti costruisci un TreeStore e lo riempi. Poi, lo usi per creare il
TreeView. A questo punto, operi sul TreeModel, e il widget farà tutto da
solo, rendendoti la vita *molto* più facile, specie se devi operare
spesso sull'albero/sulla lista. Il solo fatto di avere un widget solo e
di poterti scrivere tutti i modelli che preferisci rendono le cose molto
più semplici.
# Modello con una sola colonna (dati di tipo stringa)
model = gtk.TreeStore(gobject.TYPE_STRING)
# Riempimento dell'albero.
# insert_before restituisce un GtkTreeIter, cioé un puntatore alla riga.
# Per trovare una cella, basta usare la combinazione (iter, column_id).
# Gli iteratori sono oggetti che si "consumano", cioé sono istantanee
# dello stato del modello. Se il modello cambia, l'iteratore potrebbe
# non essere più valido. Purtroppo, c'è un unico difetto: l'iterazione
# funziona come una Singly Linked List, quindi esiste il modo per
# iterare fino alla fine del modello, ma non fino al suo inizio. Per
# farlo, ci sono delle "sporche", come spostarsi all'inizio ed iterare
# fino al punto desiderato, usando il path, ovvero la rappresentazione
# in stringa del percorso fino al nodo figlio che si sta cercando.
root = model.insert_before(None, None)
model.set_value(root, "Hello, my name is Root")
node = model.insert_before(root, None)
model.set_value(node, "And I'm Child 1", 0)
node = model.insert_before(root, node)
model.set_value(node, "And I'm Child 2", 0)
node = model.insert_before(root, node)
model.set_value(node, "And I'm Child 3", 0)
node = model.insert_before(node, None)
model.set_value(node, "I'm Granchild 1", 0)
# Widget
view = gtk.TreeView(model)
# CellRenderer, ovvero il widget che andrà a finire all'interno della
# cella. Ha varie opzioni, tra cui quella di essere editabile.
renderer = gtk.CellRendererText()
# Colonna
column = gtk.TreeViewColumn("Column", renderer, text=0)
view.append_column(column)
+++
Un TreeView modificato, che usa una lista e non un albero, lo trovi
dentro il mio programma in Python/GTK:
http://digilander.iol.it/ebassi/gnome_schedule/GNOMESchedule-1.2.tar.gz


 sicuramente più interessante.
già, però almeno il treeView delle 2.0.* è buggatino e crasha spesso...
Se poi ha più di un processo che gira è la sagra.

 
http://digilander.iol.it/ebassi/gnome_schedule/GNOMESchedule-1.2.tar.gz
Avevo gia dato uno sguardo al tuo sito, una curiosità, l'interfaccia di
gnome_schedule l'hai scritta a mano oppure hai utilizzato qualche tool
automatico?


 nodo è una foglia o meno.
Bingo!!!
Il problema sta nel fatto che la chiamata di insert_node che utilizzavo
è una versione ridotta nella quale ci sono tutta una serie di parametri
di default, tra i quali apputno is_leaf posto però di default a TRUE, mi
è bastato utilizzare la versione estesa per risolvere il problema :-)
Grazie ragazzi.


 Se poi ha più di un processo che gira è la sagra.
A parte un po' di lentezza con le prime release, di bug veri e propri
non ne ho trovati (uso non intensivo in un programma a processo
singolo)... Ad ogni modo, adesso sto provando le 2.2.0, e ci sono vari
bugfix...


 automatico?
A mano. Non mi è mai piaciuto disegnare le GUI: le preferisco
funzionali, e disegnandole, IMHO, si può perdere questo aspetto molto
facilmente...


 sbaglio?
se l'applicazione è scritta _bene_ (mai vista nessuna di una certa
dimensione) basta ricompilare.