The attached files may help another newbie understand how the TreeView works. When run, it displays a simple column with both a pixbuf and a text string.

-dave
(some text for GOOGLE here:)
#this "text=X" is the column number
cellpb = gtk.CellRendererPixbuf()
column=gtk.TreeViewColumn("Name", cellpb, pixbuf=1)
cell = gtk.CellRendererText()
column.pack_start(cell, False) #here we pack a text "column" into the same column
column.add_attribute(cell, 'text', 2) #column 2 is in "Name" but is a text column

cell.set_property('xalign', 1.0)
self.nodetree.append_column(column)
model=gtk.TreeStore(gobject.TYPE_PYOBJECT,gtk.gdk.Pixbuf,gobject.TYPE_STRING)
self.nodetree.set_model(model)
myiter=model.insert_after(None,None)
model.set_value(myiter,0,self) #NOT A VISIBLE COLUMN (since text=0 has never been set)
model.set_value(myiter,1,filepb) #Set the icon in the first column
model.set_value(myiter,2,"hi") #set the text in the FIRST VISIBLE COLUMN


Doug Quale wrote:

dave <[EMAIL PROTECTED]> writes:



So I just finished going through the treeview documentation and
tutorials, and I'm a little confused (not uncommon for me). My goal is
to do two things:
1. Have each line in the treeview connected to an object and let the
object tell the treeview what to display, and when it needs to update
the display.
2. Optionally also somehow have some of the lines have icons as well
as text. (The texts make references to "HBOX-like capabilities" - but
I don't see any way of packing arbitrary widgets into the cell render
(i.e. a text widget and a icon).)

Does anyone have a quick hint?



Maybe someone else will be able to give you something quicker. The main references are the pygtk tutorial at http://www.pygtk.org/pygtk2tutorial/index.html and the pygtk FAQ at http://www.async.com.br/faq/pygtk/index.py?req=index. You've probably read those, but if you haven't, make sure you look through the treeview sections first.

The first thing to say about the treeview is that it is hard to get
started with it.  It certainly confused me.  I promise that if you try
out the examples it will slowly make more sense.

1. One approach to using python objects as rows in a treeview is to
create a custom treemodel.  Now that I've mentioned custom treemodels
forget about them for now and instead use treeview cell data functions
because they're much simpler.  There are two examples in the FAQ,
entries 13.24 and 13.29.  The pygtk tutorial has an even better
example, filelisting.py, which is described in tutorial section
14.4.5.  A good approach might be to try that program and modify it
step by step to fit your needs.

2. Gtk+ doesn't allow packing arbitrary widgets into cells.  For now
we have only cell renderers for text, pixbufs and toggle buttons.  (A
cell renderer for comboboxes is on the way for gtk+ 2.6.)  Fortunately
all you need is text and pixbuf.  John Finlay's tutorial
filelisting.py example shows you what you need to do.  The pygtk FAQ
item 13.6 also shows an example of using CellRendererText and
CellRendererPixbuf.  You can pack multiple renderers into a single
column or you can put each in a different column.

I didn't actually give a complete answer to 1) because you want the
treeview to update when an object in the model changes.  The examples
don't show that.  To do this you need to emit the 'row-changed' signal
after any change to an object that should cause the treeview to
update.  The call to use is model.row_changed(path,iter).  If each
model object knows where it is in the model (the path or the iter),
this is easy.  Unfortunately often model objects don't know their own
path.  This is basically the same issue as putting an object in a
container such as a list.  Generally the object won't know its
position in the list (or even be aware that it's in a list) and in
fact it could easily be in multiple lists at once.

I don't have a recommendation for the best way to manage this.  It
probably depends on specifics of your application.  Simple approaches
include searching the model for the object to find its position (slow
if the model is large) and storing the path in each object in the
model (annoying updates required if rows are reordered or deleted or
inserted anywhere but the end, and even harder to do if objects can be
shared between multiple models).  To avoid some of the annoyances of
storing the path in each object you could instead store a gtk+ row
proxy.  Gtk+ tree row proxies observe the model and always know their
own path.  There are more general solutions using tree row proxies as
well.  This isn't easy to describe, so I hope someone else will have a
brilliantly simple suggestion, or at least a better explanation.

If you try the tutorial and FAQ examples out and can't figure out how
to get from there to where you want to go, post another question and
someone will probably be able to help you. On the bright side, you
didn't ask (yet) about treeview drag and drop -- that's another can of
worms.
_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/




Attachment: newgui.glade
Description: application/glade

#!/usr/bin/env python

"""
newgui.py - a test file for the new gui
"""




import os
import sys
sys.path.append("/usr/local/lib/python2.2/site-packages/")

#This program requires GTK 1.2
#make sure the python in your current path can use GTK 1.2 - check to make sure
#/usr/bin/python and /usr/local/bin/python are the same if you have problems
#on one account and not on others.

def try_import():
    import sys
    """tries to import gtk and if successful, returns 1"""
    print "Attempting to load gtk...Path=%s"%sys.path
    # To require 1.2
    try:
        import pygtk
        pygtk.require("2.0")
    except:
        print "pyGTK not found. You need GTK 2 to run this."
        print "Did you \"export PYTHONPATH=/usr/local/lib/python2.2/site-packages/\" 
first?"
        print "Perhaps you have GTK2 but not pyGTK, so I will continue to try loading."
        
        
    try:
        import gtk,gtk.glade
        import atk,pango #for py2exe
        import gobject
    except:
        import traceback,sys
        traceback.print_exc(file=sys.stdout)
        print "I'm sorry, you apparantly do not have GTK2 installed - I tried"
        print "to import gtk, gtk.glade, and gobject, and I failed."
        print "Please contact Immunity CANVAS Support and let them know what version 
you have"
        return 0
    return 1

if not try_import():
    site_packages=0
    #for k in sys.path:
    #    if k.count("site-packages"):
    #        print "existing site-packages path %s found\n"%k
    #        site_packages=1
    if site_packages == 0:
        from stat import *
        print "no site-packages path set, checking.\n"
        check_lib = [ "/usr/lib/python2.2/site-packages/",
                        "/usr/local/lib/python2.2/site-packages/",
                        "/usr/local/lib/python2.3/site-packages/" ]
        for k in check_lib:
            try:
                path=os.path.join(k,"pygtk.py")
                #print "Path=%s"%path
                if open(path)!=None:
                    print "appending", k
                    sys.path=[k]+sys.path
                    if try_import():
                        break
            except:
                pass
    if not try_import():
        sys.exit(0)
        
import gtk,gtk.glade
import atk,pango #for py2exe
import gobject
filexpm = [
    "12 12 3 1",
    "  c #000000",
    ". c #ffff04",
    "X c #b2c0dc",
    "X        XXX",
    "X ...... XXX",
    "X ......   X",
    "X .    ... X",
    "X ........ X",
    "X .   .... X",
    "X ........ X",
    "X .     .. X",
    "X ........ X",
    "X .     .. X",
    "X ........ X",
    "X          X"
    ]
filepb = gtk.gdk.pixbuf_new_from_xpm_data(filexpm)

class newgui:
    def __init__(self):
        self.init_app()
    
    def init_app (self):
        "Initialise the application."
        
        #window1 must be the main app window!!!
        self.wTree = gtk.glade.XML ("newgui.glade", "window1")
        dic = {"on_quit_button_clicked"        : self.quit,
                "on_window1_destroy" : (self.quit),
                }
        self.window=self.wTree.get_widget("window1") # sure there must be another way
        self.handlers={}        
        self.wTree.signal_autoconnect (dic)
        self.nodetree=self.wTree.get_widget("nodeview")
        
        #set up columns

        #this "text=X" is the column number
        cellpb = gtk.CellRendererPixbuf()
        column=gtk.TreeViewColumn("Name", cellpb, pixbuf=1)
        cell = gtk.CellRendererText()
        column.pack_start(cell, False) #here we pack a text "column" into the same 
column
        column.add_attribute(cell, 'text', 2) #column 2 is in "Name" but is a text 
column

        cell.set_property('xalign', 1.0)
        self.nodetree.append_column(column)

        
        model=gtk.TreeStore(gobject.TYPE_PYOBJECT,gtk.gdk.Pixbuf,gobject.TYPE_STRING)
        self.nodetree.set_model(model)
        myiter=model.insert_after(None,None)
        model.set_value(myiter,0,self) #NOT A VISIBLE COLUMN (since text=0 has never 
been set)
        model.set_value(myiter,1,filepb) #Set the icon in the first column
        model.set_value(myiter,2,"hi") #set the text in the FIRST VISIBLE COLUMN
        return

        

        
    def quit(self,args):
        gtk.mainquit()
        return
    
    
if __name__ == '__main__':

    #do splashscreen here maybe
    mygui=newgui()
    #hmmm
    try:
        gtk.threads_init()
    except:
        print "No threading was enabled when you compiled pyGTK!"
        sys.exit(1)
    gtk.threads_enter()
    gtk.mainloop ()
    gtk.threads_leave()

<<inline: newgui.png>>

_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to