As I'm sure everyone knows, using TreeViews can be a bit intimidating for new
PyGTK users, especially when they really only want a simple list instead of a
full tree.
I've put together a rather simpler API that works well for me, covers the 80% I
need for lists. There's some work that still needs to be done for robustness
and to cover off the other 20%, but some feedback on the API itself at this
stage would be really helpful.
==documentation by example==
#very simple item for example
class simpleItem:
def __init__(self, val):
self.number = val
self.name = 'Foo'
def even(self):
return self.number % 2 == 0
def odd(self):
return self.number % 2 == 1
#implemented as a wrapper around treeview widget
# easy to wrap Glade widgets this way
tree = SimpleTree(gtk.TreeView())
#window.add(tree.tv) #underlying treeview widget
#simply provide a list of objects
#no reason we can't extend to basic data types
sampleList = [simpleItem(1),simpleItem(2),simpleItem(3)]
tree.model = sampleList
#columns to display; can be properties or methods
# - future version will allow tuples with header text and type
tree.setCols(["number", "name", "even"])
#future - tree.cols = [("icon", "Status", gtk.PixBuf), ("name", "Article Name",
str)]
#optional designate a property/method to handle row visibility
tree.visibility = "odd"
#do the usual list manipulation
sampleList.append(simpleItem(4))
#get the selected item
# - future version will return array of objects when multi-select
tree.selected.name = "Edited"
# future - tree.selected[0].name = "Edited"
#call whenever changes have been made
tree.refresh()
==simpleTree.py===============
#Copyright 2004 John C Barstow
#distributed under same license as PyGTK package.
def simpleItemProperty(column, cell_renderer, tree_model, iter, user_data):
item = tree_model.get_value(iter, 0)
if item == None:
return
prop = getattr(item,user_data)
if(callable(prop)):
prop = prop()
cell_renderer.set_property('text', prop)
def simpleItemVisible(tree_model, iter, user_data):
item = tree_model.get_value(iter, 0)
if item == None:
return False
prop = getattr(item,user_data)
if(callable(prop)):
prop = prop()
return prop
class SimpleTree(object):
def __init__(self, treeview):
self.tv = treeview
def createCols(self):
cell = gtk.CellRendererText()
col = gtk.TreeViewColumn("col1")
col.pack_start(cell, True)
col.set_attributes(cell, text=0)
self.tv.append_column(col)
def setModel(self, l):
self.baseList = l
self.tree = gtk.ListStore(object)
[self.tree.append([item]) for item in l]
self.tv.set_model(self.tree)
def setVisibility(self, prop):
self.filter = self.tree.filter_new()
self.filter.set_visible_func(simpleItemVisible, prop)
self.tv.set_model(self.filter)
def refresh(self):
existingItems = [o[0] for o in self.tree]
for item in self.baseList:
if item not in existingItems:
self.tree.append([item])
else:
existingItems.remove(item)
for item in existingItems:
iters = [o for o in self.tree if o[0] == item]
for row in iters:
i = row.iter
self.tree.remove(i)
if hasattr(self, "filter"):
self.filter.refilter()
def setCols(self, cols):
#self.tv.clear()
[self.addCol(col) for col in cols]
def addCol(self, prop):
cell = gtk.CellRendererText()
col = gtk.TreeViewColumn(prop, cell)
col.set_cell_data_func(cell, simpleItemProperty, prop)
self.tv.append_column(col)
def getSelected(self):
model, iter = self.tv.get_selection().get_selected()
return model[iter][0]
model = property(None, setModel)
selected = property(getSelected, None)
visibility = property(None, setVisibility)
==================END===========================
==example.py====================================
from simpleTree import *
class SimpleTreeDriver:
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return gtk.FALSE
def createList(self):
self.list = [simpleItem(1),simpleItem(2),simpleItem(3)]
self.nextNum = 4
self.tv = SimpleTree(gtk.TreeView())
self.tv.model = self.list
self.tv.setCols(["number", 'name', "cat"])
def __init__(self):
# Create a new window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_size_request(300, 200)
self.window.connect("delete_event", self.delete_event)
self.createList()
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.add(self.tv.tv)
buttons = gtk.HButtonBox()
rembtn = gtk.Button(stock=gtk.STOCK_REMOVE)
rembtn.connect("clicked", self.remove)
buttons.add(rembtn)
addbtn = gtk.Button(stock=gtk.STOCK_ADD)
addbtn.connect("clicked", self.add)
buttons.add(addbtn)
evenbtn = gtk.Button("Even")
evenbtn.connect("clicked", self.even)
buttons.add(evenbtn)
buttons.set_spacing(6)
buttons.set_layout(gtk.BUTTONBOX_END)
vframe = gtk.VBox(spacing=6)
vframe.pack_start(self.scrolledwindow, expand=True, fill=True)
vframe.pack_start(buttons, expand=False, fill=False)
self.window.add(vframe)
self.window.set_title("simple tree")
self.window.set_border_width(6)
self.window.show_all()
def add(self, event):
self.list.append(simpleItem(self.nextNum))
self.nextNum += 1
self.tv.refresh()
def remove(self, event):
self.list.remove(self.tv.selected)
self.tv.refresh()
def even(self, event):
self.tv.setVisibility("even")
self.tv.refresh()
def main(self):
gtk.main()
if __name__ == "__main__":
ex = SimpleTreeDriver()
ex.main()
==================END===========================
_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/