Python-Ref > GUI programming with PyGTK > Widgets > TreeView IV. - display of trees
 
 

<-^^

TreeView IV. - display of trees

How to render trees instead of simple tabular data in the TreeView.
The following examples demonstrates rendering of tree-like structure in the TreeView. The basics are the same as in previous examples, only we use TreeStore instead of ListStore.
Expand/Shrink
  1   # ensure that PyGTK 2.0 is loaded - not an older version
  2   import pygtk
  3   pygtk.require('2.0')
  4   # import the GTK module
  5   import gtk
  6   
  7   class MyGUI:
  8   
  9     def __init__( self):
 10       self.builder = gtk.Builder()
 11       self.builder.add_from_file("infiles/treeview4-0.ui") 
 12       self.builder.connect_signals(self)
 13       self.window = self.builder.get_object("window1")
 14       self.add_data()
 15       self.window.show()
 16   
 17   
 18     def add_data(self):
 19       data = [("Books", ("Fantasy","Sci-fi","Humor")),
 20               ("Music", ("CD","Cassette","MC")),
 21               ("Other", ("Batteries",))]
 22       model = self.builder.get_object("model")
 23       for name, categories in data:
 24         parent = model.append(None, [name])
 25         for category in categories:
 26           model.append(parent, [category]) 
 27       
 28     def main( self):
 29       gtk.main()
 30   
 31     def on_window1_destroy( self, w):
 32       gtk.main_quit()
 33   
 34   
 35   if __name__ == "__main__":
 36     m = MyGUI()
 37     m.main()
Screenshot:
Program screenshot gtk-treeview4-0.png
Doba běhu: 4852.1 ms
Here we use XML as input data, because it presents a natural tree-like structure.
Expand/Shrink
<examples>
  <example num="1">
    <title>Example 1</title>
    <text>This is example nr. 1. It shows how an example looks.</text>
  </example>

  <example num="2">
    <title>Example 2</title>
    <text>Another example. Imagine some ingenious text here...</text>
  </example>
</examples>
  1   # ensure that PyGTK 2.0 is loaded - not an older version
  2   import pygtk
  3   pygtk.require('2.0')
  4   # import the GTK module
  5   import gtk
  6   import xml.dom.minidom as dom
  7   
  8   class MyGUI:
  9   
 10     def __init__( self, title, filename):
 11       self.window = gtk.Window()
 12       self.title = title
 13       self.filename = filename
 14       self.window.set_title( title)
 15       self.window.set_size_request( -1, -1)
 16       self.window.connect( "destroy", self.destroy)
 17       self.create_interior()
 18       self.window.show_all()
 19   
 20     def create_interior( self):
 21       self.mainbox = gtk.VBox()
 22       scrolled_w = gtk.ScrolledWindow()
 23       scrolled_w.set_policy( gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 24       self.window.add( self.mainbox)
 25       self.mainbox.pack_start( scrolled_w)
 26       # model creation
 27       self.model = gtk.TreeStore( str) 
 28       doc = dom.parse( self.filename)
 29       self.add_element_to_treestore( doc.childNodes[0], None)
 30       # the treeview
 31       treeview = gtk.TreeView( self.model)
 32       # columns
 33       col0 = gtk.TreeViewColumn( "Name")
 34       # cell renderers - for individual data cells rendering
 35       self.cell0 = gtk.CellRendererText()
 36       # first column
 37       treeview.append_column( col0)
 38       col0.pack_start( self.cell0)
 39       col0.set_attributes( self.cell0, text=0)
 40       col0.set_sort_column_id( 0) # make column sortable using column 0 data
 41       # add the treeview to the parent and show it
 42       scrolled_w.add( treeview)
 43       scrolled_w.set_size_request( 300, 300)
 44       treeview.show()
 45       # show mainbox
 46       self.mainbox.show()
 47   
 48     def add_element_to_treestore( self, e, parent):
 49       if isinstance( e, dom.Element):
 50         me = self.model.append( parent, [e.nodeName])
 51         for ch in e.childNodes:
 52           self.add_element_to_treestore( ch, me)
 53   
 54     def main( self):
 55       gtk.main()
 56   
 57     def destroy( self, w):
 58       gtk.main_quit()
 59   
 60   
 61   if __name__ == "__main__":
 62     m = MyGUI( "TreeView example IV.", "example.xml")
 63     m.main()
Screenshot:
Program screenshot gtk-treeview4-1.png
Doba běhu: 1920.4 ms
Expand/Shrink
<examples>
  <example num="1">
    <title>Example 1</title>
    <text>This is example nr. 1. It shows how an example looks.</text>
  </example>

  <example num="2">
    <title>Example 2</title>
    <text>Another example. Imagine some ingenious text here...</text>
  </example>
</examples>
  1   # ensure that PyGTK 2.0 is loaded - not an older version
  2   import pygtk
  3   pygtk.require('2.0')
  4   # import the GTK module
  5   import gtk
  6   import xml.dom.minidom as dom
  7   
  8   class MyGUI:
  9   
 10     def __init__( self, title, filename):
 11       self.window = gtk.Window()
 12       self.title = title
 13       self.filename = filename
 14       self.window.set_title( title)
 15       self.window.set_size_request( -1, -1)
 16       self.window.connect( "destroy", self.destroy)
 17       self.create_interior()
 18       self.window.show_all()
 19   
 20     def create_interior( self):
 21       self.mainbox = gtk.VBox()
 22       scrolled_w = gtk.ScrolledWindow()
 23       scrolled_w.set_policy( gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 24       self.window.add( self.mainbox)
 25       self.mainbox.pack_start( scrolled_w)
 26       # model creation
 27       self.model = gtk.TreeStore( str, str, str) 
 28       doc = dom.parse( self.filename)
 29       self.add_element_to_treestore( doc.childNodes[0], None)
 30       # the treeview
 31       treeview = gtk.TreeView( self.model)
 32       # columns
 33       for i,title in enumerate( ["Name","Node Type","Value"]):
 34         col = gtk.TreeViewColumn( title)
 35         # cell renderers - for individual data cells rendering
 36         cell = gtk.CellRendererText()
 37         treeview.append_column( col)
 38         col.pack_start( cell)
 39         col.set_attributes( cell, text=i)
 40         col.set_sort_column_id( i) # make column sortable using column 0 data
 41       # add the treeview to the parent and show it
 42       scrolled_w.add( treeview)
 43       scrolled_w.set_size_request( 600, 400)
 44       treeview.show()
 45       # show mainbox
 46       self.mainbox.show()
 47   
 48     def add_element_to_treestore( self, e, parent):
 49       if isinstance( e, dom.Element):
 50         me = self.model.append( parent, [e.nodeName,"ELEMENT",""])
 51         for i in range( e.attributes.length):
 52           a = e.attributes.item( i)
 53           self.model.append( me, ["@"+a.name, "ATTRIBUTE", a.value])
 54         for ch in e.childNodes:
 55           self.add_element_to_treestore( ch, me)
 56       elif isinstance( e, dom.Text):
 57         self.model.append( parent, ["text()","TEXT_NODE",e.nodeValue.strip()])
 58   
 59     def main( self):
 60       gtk.main()
 61   
 62     def destroy( self, w):
 63       gtk.main_quit()
 64   
 65   
 66   if __name__ == "__main__":
 67     m = MyGUI( "TreeView example IV.", "example.xml")
 68     m.main()
Screenshot:
Program screenshot gtk-treeview4-2.png
Doba běhu: 1631.5 ms
Expand/Shrink
<examples>
  <example num="1">
    <title>Example 1</title>
    <text>This is example nr. 1. It shows how an example looks.</text>
  </example>

  <example num="2">
    <title>Example 2</title>
    <text>Another example. Imagine some ingenious text here...</text>
  </example>
</examples>
Rozdíl proti: gtk-treeview4-2.py
@@ -24,7 +24,7 @@
     self.window.add( self.mainbox)
     self.mainbox.pack_start( scrolled_w)
     # model creation
-    self.model = gtk.TreeStore( str, str, str) 
+    self.model = gtk.TreeStore( str, str, str, str) 
     doc = dom.parse( self.filename)
     self.add_element_to_treestore( doc.childNodes[0], None)
     # the treeview
@@ -36,7 +36,7 @@
       cell = gtk.CellRendererText()
       treeview.append_column( col)
       col.pack_start( cell)
-      col.set_attributes( cell, text=i)
+      col.set_attributes( cell, text=i, cell_background=3)
       col.set_sort_column_id( i) # make column sortable using column 0 data
     # add the treeview to the parent and show it
     scrolled_w.add( treeview)
@@ -47,14 +47,14 @@
   def add_element_to_treestore( self, e, parent):
     if isinstance( e, dom.Element):
-      me = self.model.append( parent, [e.nodeName,"ELEMENT",""])
+      me = self.model.append( parent, [e.nodeName,"ELEMENT","","#CCCCFF"])
       for i in range( e.attributes.length):
         a = e.attributes.item( i)
-        self.model.append( me, ["@"+a.name, "ATTRIBUTE", a.value])
+        self.model.append( me, ["@"+a.name, "ATTRIBUTE", a.value, "#CCFFCC"])
       for ch in e.childNodes:
         self.add_element_to_treestore( ch, me)
     elif isinstance( e, dom.Text):
-      self.model.append( parent, ["text()","TEXT_NODE",e.nodeValue.strip()])
+      self.model.append( parent, ["text()","TEXT_NODE",e.nodeValue.strip(),"#FFFFCC"])
   def main( self):
     gtk.main()
Screenshot:
Program screenshot gtk-treeview4-3.png
Doba běhu: 1238.3 ms
Expand/Shrink
<examples>
  <example num="1">
    <title>Example 1</title>
    <text>This is example nr. 1. It shows how an example looks.</text>
  </example>

  <example num="2">
    <title>Example 2</title>
    <text>Another example. Imagine some ingenious text here...</text>
  </example>
</examples>
Rozdíl proti: gtk-treeview4-3.py
@@ -38,6 +38,9 @@
       col.pack_start( cell)
       col.set_attributes( cell, text=i, cell_background=3)
       col.set_sort_column_id( i) # make column sortable using column 0 data
+      if i in (0,2):
+        cell.set_property( "editable", True)
+        cell.connect( "edited", self._text_edited, i)
     # add the treeview to the parent and show it
     scrolled_w.add( treeview)
     scrolled_w.set_size_request( 600, 400)
@@ -56,10 +59,36 @@
     elif isinstance( e, dom.Text):
       self.model.append( parent, ["text()","TEXT_NODE",e.nodeValue.strip(),"#FFFFCC"])
+  def _text_edited( self, w, row, new_value, column):
+    self.model[row][column] = new_value
+
+  def model_to_xml( self):
+    doc = dom.Document()
+    self.add_row_to_xml( self.model[0], doc, doc)
+    return doc
+
+  def add_row_to_xml( self, row, parent, doc):
+    node_type = row[1]
+    if node_type == "ELEMENT":
+      e = doc.createElement( row[0])
+      for child in row.iterchildren():
+        self.add_row_to_xml( child, e, doc)
+      parent.appendChild( e)
+    elif node_type == "TEXT_NODE":
+      t = doc.createTextNode( row[2])
+      parent.appendChild( t)
+    elif node_type == "ATTRIBUTE":
+      parent.setAttribute( row[0], row[2])
+    else:
+      print "this should not happen"
+      
+
   def main( self):
     gtk.main()
   def destroy( self, w):
+    doc = self.model_to_xml()
+    print doc.toxml()
     gtk.main_quit()
stdout:
<?xml version="1.0" ?>
<new_examples><example @num="20"><title>Title edited</title><text>This is example nr. 1. It shows how an example looks.</text></example><example @num="2"><title>Example 2</title><text>Another example. Imagine some ingenious text here...</text></example></new_examples>
Screenshot:
Program screenshot gtk-treeview4-4.png
Doba běhu: 39938.7 ms