Bin hier neu im Board, komme aber gleich mit einer kniffligen Fragestellung zu euch. Ich hoffe mal, dass ich mein problem praezise genug beschreiben kann, um euren anspruechen zu genuegen.
Ich versuche momentan ein gtk.GenericTreeModel zu implementieren, komme aber noch nicht soganz dahinter wie das funktioniert. Um einen kleinen Einblick zu gewaehren hab ich ein Testscript angefertigt um das Problem auf das wesentliche zu reduzieren. Im endeffekt moechte ich erreichen, dass mein TreeModel direkt mit Objekten bestueckt werden kann (im beispiel Object1 und Object2), die ein parent- und ein children-attribut besitzen um die baumstruktur auszudruecken.
Ich vermute, dass mein fehler schon allein damit beginnt, dass ich versuche einen gtk.TreeIter mit meinen Objekten zu implementieren. Von den Dokumentationen ausgehend habe ich bisher angenommen, ein gtk.TreeIter sei eine referenz auf eine bestimmte zeile im treestore.
Wie handle ich TreeIter und vor allem, wie kann ich welche erzeugen(abstrakte klasse)? Wie verknuepfe ich TreeIter und datensatz miteinander? Wieso besteht der iter, den ich aus dem model ziehe die validTreeIter pruefung nicht?
Wenn hier irgendjemand Licht ins dunkel bringen koennte, waere ich demjenigen sehr dankbar.
Code: Alles auswählen
import pygtk
pygtk.require('2.0')
import gtk
class Object1(gtk.TreeIter):
def __init__(self):
self.id = None
self.name = None
self.parent = None
self.children = []
class Object2(gtk.TreeIter):
def __init__(self):
self.id = None
self.name = None
self.parent = None
self.children = []
class ObjectTreeModel(gtk.GenericTreeModel):
COLUMN_NAMES = ('ID','Name')
COLUMN_TYPES = (int, str)
def __init__(self):
gtk.GenericTreeModel.__init__(self)
root = Object1()
root.id = 0
root.name = 'root'
self.items = [root]
def on_get_flags(self):
return 0
def on_get_n_columns(self):
return (len(self.COLUMN_NAMES)+1)
def on_get_column_type(self, index):
return self.COLUMN_TYPES[index]
def on_get_iter(self,path):
cur_element = self.items
for number in path:
try:
if cur_element == self.items:
cur_element = cur_element[number]
else:
cur_element = cur_element.children[number]
except IndexError, e:
return None
return cur_element
def on_get_path(self, rowref):
tree = self.items
path = {}
treelevel = 0
def searchSubTree(subtree,rowref, path, treelevel):
for x in xrange(0,len(subtree)):
path[treelevel] = x
if subtree[x] == rowref:
return path
elif len(subtree[x].children)!=0:
treelevel+=1
searchSubTree(subtree[x].children,rowref,path,treelevel)
treelevel-=1
else:
pass
path = searchSubTree(tree,rowref,path,treelevel)
return tuple(path.values())
def on_get_value(self,rowref,column):
assert column in (0,1)
if column == 0:
return rowref.id
else:
return rowref.name
def on_iter_next(self,rowref):
if rowref.parent!= None:
parent = rowref.parent
try:
nextchild = parent.children[parent.children.index(rowref)+1]
except IndexError,e:
return None
else:
return nextchild
def on_iter_children(self,rowref):
if parent is None:
return None
else:
try:
child = rowref.children[0]
return child
except IndexError,e:
return None
def on_iter_has_child(self, rowref):
return len(rowref.children) > 0
def on_iter_n_children(self, rowref):
return len(rowref.children)
def on_iter_nth_child(self, parent, n):
try:
child = parent.children[n]
return child
except Exception,e:
return None
def on_iter_parent(self, child):
return child.parent
class TestApp(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.treeview = gtk.TreeView()
self.model = ObjectTreeModel()
self.treeview.set_model(self.model)
self.col_id = gtk.TreeViewColumn('Id')
self.col_name = gtk.TreeViewColumn('Name')
self.renderer_id = gtk.CellRendererText()
self.renderer_name = gtk.CellRendererText()
self.treeview.append_column(self.col_id)
self.treeview.append_column(self.col_name)
self.col_id.pack_start(self.renderer_id,False)
self.col_name.pack_start(self.renderer_name,False)
self.col_id.add_attribute(self.renderer_id,'text',0)
self.col_name.add_attribute(self.renderer_name,'text',1)
self.add(self.treeview)
self.show_all()
win = TestApp()
gtk.main()
dazu braeucht ich halt nur mal das grundgeruest.