Python-Ref > GUI programming with PyGTK > Widgets > TreeView
 
 

<-^^->

TreeView

Powerful widget for display of tabular and tree-like data.
The internal workings of a TreeView are pretty complicated and could be overwhelming at first glimpse. The following picture tries to show how different objects that act inside the TreeView work together.
TreeView structure explanation
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, title):
 10       self.window = gtk.Window()
 11       self.title = title
 12       self.window.set_title( title)
 13       self.window.set_size_request( -1, -1)
 14       self.window.connect( "destroy", self.destroy)
 15       self.create_interior()
 16       self.window.show_all()
 17   
 18     def create_interior( self):
 19       self.mainbox = gtk.VBox()
 20       scrolled_w = gtk.ScrolledWindow()
 21       scrolled_w.set_policy( gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 22       self.window.add( self.mainbox)
 23       self.mainbox.pack_start( scrolled_w)
 24       # model creation
 25       model = gtk.ListStore( str, gtk.gdk.Pixbuf, str) 
 26       for stock in gtk.stock_list_ids():
 27         desc = gtk.stock_lookup( stock)
 28         # for some reason the lookup sometimes fails :(
 29         if desc != None:
 30           pixbuf = self.window.render_icon( stock_id=stock, size=gtk.ICON_SIZE_MENU) 
 31           label = desc[1]
 32           model.append( [stock, pixbuf, label])
 33       # the treeview
 34       treeview = gtk.TreeView( model)
 35       # columns
 36       col0 = gtk.TreeViewColumn( "stock_id")
 37       col1 = gtk.TreeViewColumn( "picture and label")
 38       # cell renderers - for individual data cells rendering
 39       self.cell0 = gtk.CellRendererText()
 40       self.cell1 = gtk.CellRendererPixbuf()
 41       self.cell2 = gtk.CellRendererText()
 42       # add columns to treeview and cell renderers to columns
 43       # first column
 44       treeview.append_column( col0)
 45       # pack the cell renderer to the column
 46       col0.pack_start( self.cell0)
 47       # set cell0.text to be taken from model column 0
 48       col0.set_attributes( self.cell0, text=0)
 49       col0.set_sort_column_id( 0) # make column sortable using column 0 data
 50       self.cell0.connect( 'edited', self._text_edited, model) 
 51       # second column
 52       treeview.append_column( col1)
 53       # pack two cell renderers to the column
 54       col1.pack_start( self.cell1)
 55       col1.pack_start( self.cell2)
 56       # set cell1.pixbuf to be taken from model col 1 and cell2.text from col 2
 57       col1.set_attributes( self.cell1, pixbuf=1)
 58       col1.set_attributes( self.cell2, text=2)
 59       scrolled_w.add( treeview)
 60       scrolled_w.set_size_request( 400, 400)
 61       treeview.show()
 62       # add some buttons
 63       hbox = gtk.HBox()
 64       self.mainbox.pack_end( hbox, expand=False)
 65       hbox.show()
 66       b1 = gtk.CheckButton( "Show colors")
 67       hbox.pack_start( b1)
 68       b1.show()
 69       b1.connect( "toggled", self.color_toggled)
 70       b2 = gtk.CheckButton( "Editable column 1")
 71       hbox.pack_start( b2)
 72       b2.show()
 73       b2.connect( "toggled", self.editable_toggled)
 74       # show mainbox
 75       self.mainbox.show()
 76   
 77     def color_toggled( self, w):
 78       if w.get_active():
 79         self.cell0.set_property( "cell-background", "yellow")
 80         self.cell2.set_property( "cell-background", "green")
 81       else:
 82         self.cell0.set_property( "cell-background", "white")
 83         self.cell2.set_property( "cell-background", "white")
 84       self.window.queue_draw() # forces redraw 
 85   
 86     def editable_toggled( self, w):
 87       if w.get_active():
 88         self.cell0.set_property( "editable", True)
 89       else:
 90         self.cell0.set_property( "editable", False)
 91   
 92     def _text_edited( self, w, row, new_text, model):
 93       model[row][0] = new_text
 94   
 95     def main( self):
 96       gtk.main()
 97   
 98     def destroy( self, w):
 99       gtk.main_quit()
100   
101   
102   if __name__ == "__main__":
103     m = MyGUI( "TreeView example")
104     m.main()
Screenshot:
Program screenshot gtk-treeview1-1.pngProgram screenshot gtk-treeview1-1a.png
Doba běhu: 1146.9 ms
Expand/Shrink
Country|Currency|Amount|Code|Rate
Australia|dollar|1|AUD|14.774
Brazil|real|1|BRL|9.370
Bulgaria|lev|1|BGN|12.855
Canada|dollar|1|CAD|15.550
China|renminbi|1|CNY|2.265
Croatia|kuna|1|HRK|3.461
Denmark|krone|1|DKK|3.370
EMU|euro|1|EUR|25.145
Estonia|kroon|1|EEK|1.607
Hongkong|dollar|1|HKD|2.034
Hungary|forint|100|HUF|9.922
Iceland|krona|100|ISK|21.759
IMF|SDR|1|XDR|26.052
Indonesia|rupiah|1000|IDR|1.723
Japan|yen|100|JPY|15.798
Latvia|lats|1|LVL|36.092
Lithuania|litas|1|LTL|7.283
Malaysia|ringgit|1|MYR|5.026
Mexico|peso|1|MXN|1.498
New Zealand|dollar|1|NZD|12.671
Norway|krone|1|NOK|3.172
Philippines|peso|100|PHP|38.121
Poland|zloty|1|PLN|7.305
Romania|new leu|1|RON|6.854
Russia|rouble|100|RUB|67.640
Singapore|dollar|1|SGD|11.675
Slovakia|koruna|100|SKK|77.734
South Africa|rand|1|ZAR|2.004
South Korea|won|100|KRW|1.622
Sweden|krona|1|SEK|2.679
Switzerland|franc|1|CHF|15.978
Thailand|baht|100|THB|50.236
Turkey|new lira|1|TRY|12.057
United Kingdom|pound|1|GBP|31.394
USA|dollar|1|USD|15.839
  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, title, filename): 
 10       self.window = gtk.Window()
 11       self.title = title
 12       self.filename = filename
 13       self.window.set_title( title)
 14       self.window.set_size_request( -1, -1)
 15       self.window.connect( "destroy", self.destroy)
 16       self.create_interior()
 17       self.window.show_all()
 18   
 19     def create_interior( self):
 20       self.mainbox = gtk.ScrolledWindow()
 21       self.mainbox.set_policy( gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 22       self.window.add( self.mainbox)
 23       # model creation
 24       model = gtk.ListStore( str, str, int, str, float) 
 25       f = file( self.filename, "r")
 26       header = f.readline().strip().split("|") # header in first line
 27       for line in f:
 28         data = line.strip().split("|")
 29         data[2] = int( data[2])
 30         data[4] = float( data[4])
 31         model.append( data)
 32       f.close()
 33       # the treeview
 34       treeview = gtk.TreeView( model) 
 35       # cell renderers - for individual data cells rendering
 36       cells = [gtk.CellRendererText() for i in range( len( header))] 
 37       # columns
 38       cols = [gtk.TreeViewColumn( title) for title in header] 
 39       for i,col in enumerate( cols):
 40         treeview.append_column( col) 
 41         col.pack_start( cells[i], expand=False) 
 42         col.set_attributes( cells[i], text=i) 
 43         col.set_sort_column_id( i) 
 44       self.mainbox.add( treeview)
 45       treeview.show()
 46       treeview.connect( "row-activated", self.row_activated) 
 47       # show the box
 48       self.mainbox.set_size_request( 460, 400)
 49       self.mainbox.show()
 50   
 51     def row_activated( self, tree, path, column):
 52       model = tree.get_model() 
 53       iter = model.get_iter( path) 
 54       country = model.get_value( iter, 0) 
 55       d = gtk.MessageDialog( parent=self.window,
 56                              type=gtk.MESSAGE_INFO,
 57                              flags=gtk.DIALOG_DESTROY_WITH_PARENT,
 58                              buttons=gtk.BUTTONS_CLOSE,
 59                              message_format="You selected currency of %s." % country
 60                              )
 61       result = d.run()
 62       d.destroy()
 63   
 64     def main( self):
 65       gtk.main()
 66   
 67     def destroy( self, w):
 68       gtk.main_quit()
 69   
 70   
 71   if __name__ == "__main__":
 72     m = MyGUI( "TreeView example", "exchange.txt") 
 73     m.main()
Screenshot:
Program screenshot gtk-treeview1-2.pngProgram screenshot gtk-treeview1-2a.pngProgram screenshot gtk-treeview1-2b.png
Doba běhu: 1505.5 ms
The following is the same but with GtkBuilder used.
Expand/Shrink
Country|Currency|Amount|Code|Rate
Australia|dollar|1|AUD|14.774
Brazil|real|1|BRL|9.370
Bulgaria|lev|1|BGN|12.855
Canada|dollar|1|CAD|15.550
China|renminbi|1|CNY|2.265
Croatia|kuna|1|HRK|3.461
Denmark|krone|1|DKK|3.370
EMU|euro|1|EUR|25.145
Estonia|kroon|1|EEK|1.607
Hongkong|dollar|1|HKD|2.034
Hungary|forint|100|HUF|9.922
Iceland|krona|100|ISK|21.759
IMF|SDR|1|XDR|26.052
Indonesia|rupiah|1000|IDR|1.723
Japan|yen|100|JPY|15.798
Latvia|lats|1|LVL|36.092
Lithuania|litas|1|LTL|7.283
Malaysia|ringgit|1|MYR|5.026
Mexico|peso|1|MXN|1.498
New Zealand|dollar|1|NZD|12.671
Norway|krone|1|NOK|3.172
Philippines|peso|100|PHP|38.121
Poland|zloty|1|PLN|7.305
Romania|new leu|1|RON|6.854
Russia|rouble|100|RUB|67.640
Singapore|dollar|1|SGD|11.675
Slovakia|koruna|100|SKK|77.734
South Africa|rand|1|ZAR|2.004
South Korea|won|100|KRW|1.622
Sweden|krona|1|SEK|2.679
Switzerland|franc|1|CHF|15.978
Thailand|baht|100|THB|50.236
Turkey|new lira|1|TRY|12.057
United Kingdom|pound|1|GBP|31.394
USA|dollar|1|USD|15.839
  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, filename): 
 10       self.builder = gtk.Builder()
 11       self.builder.add_from_file("infiles/treeview1-3.ui") 
 12       self.builder.connect_signals(self)
 13       self.window = self.builder.get_object("window1")
 14       self.load_data(filename)
 15       self.window.show()
 16   
 17   
 18     def load_data(self, filename):
 19       # model creation
 20       model = self.builder.get_object("my_liststore") 
 21       f = file(filename, "r")
 22       header = f.readline().strip().split("|") # header in first line
 23       for line in f:
 24         data = line.strip().split("|")
 25         data[2] = int( data[2])
 26         data[4] = float( data[4])
 27         model.append( data)
 28       f.close()
 29       # the treeview
 30       treeview = self.builder.get_object("my_treeview")
 31       treeview.connect( "row-activated", self.row_activated) 
 32       treeview.set_size_request( 460, 400)
 33   
 34     def row_activated( self, tree, path, column):
 35       model = tree.get_model() 
 36       iter = model.get_iter( path) 
 37       country = model.get_value( iter, 0) 
 38       d = gtk.MessageDialog( parent=self.window,
 39                              type=gtk.MESSAGE_INFO,
 40                              flags=gtk.DIALOG_DESTROY_WITH_PARENT,
 41                              buttons=gtk.BUTTONS_CLOSE,
 42                              message_format="You selected currency of %s." % country
 43                              )
 44       result = d.run()
 45       d.destroy()
 46   
 47     def main( self):
 48       gtk.main()
 49   
 50     def on_window1_destroy( self, w):
 51       gtk.main_quit()
 52   
 53   
 54   if __name__ == "__main__":
 55     m = MyGUI("exchange.txt") 
 56     m.main()
Screenshot:
Program screenshot gtk-treeview1-3.png
Doba běhu: 1342.3 ms