On 10/14/2009 06:52 PM, Daniel B. Thurman wrote: [snip!] Apologies. It appears that there is something wrong with email-deliveries and I am not getting every posting, so I will have to reply to certain individuals that I have not received directly into my mailbox. (I am looking directly at the archives for those I have missed) ==================================== David Nečas <yeti physics muni cz> (1) The signal is called "row-expanded". [Dan] Thank you! But how did you find this signal? (2) You have the text in another column instead of directly in the expander column? [Dan] I have posted the experimental code & hopefully the post is accepted. ==================================== Shaun McCance <shaunm gnome org> (1) If you want to populate data on-demand like this, you're probably going to have to write your own GtkTreeModel. [Dan] Ugh. I will try to use the stock and see if I can get this to work first! ==================================== Holger Berndt <berndth gmx de> (sent directly to me) The way I do that is to add a single dummy child (with a text like "Loading..."). That makes the top level entry expandable. When the user expands the item, he gets feedback right away by seeing the "Loading..." entry, while the code populates the model on the fly, and finally removes the dummy entry. Others (e.g. Nautilus list view) seem to do it similarly. [Dan- All below] The problem I have is: how do I capture the signal when the row is expanded? I posted a follow up on this and it seems that the key is "row-has-child-toggled", but this does not seem to work: self.treeview.connect('row-has-child-toggled', self.on_row_activated) TypeError: <gtk.TreeView object at 0xb7b9ab6c (GtkTreeView at 0x8df5080)>: unknown signal name: row-has-child-toggled I have, however tried: self.treeview.connect('row-activated', self.on_row_activated) and this works, except that the row has to be mouse double-clicked, which is not what I want. I sure wish there is a Python-GTK code somewhere that I could peruse to resolve my many issues! Since the code I have is experimental, I include it in the following, so that it is open to critique and may be of benefit to others following the same pathway: ================================== [code] #!/usr/bin/env python import os, stat, sys, time import pygtk pygtk.require('2.0') import gtk DEBUG=True RECURSE=1 SEP=' ' DEFAULT_PATH='~/Desktop/' class FileLister: # column_names = ['Files', 'Size', 'Mode', 'Last Changed', 'Path'] column_names = ['Files'] # Close the window and quit def delete_event(self, widget, event, data="" gtk.main_quit() return False def __init__(self, path=None): cell_data_funcs = ( None, self.file_size, self.file_mode, self.file_last_changed, self.file_path) # Create a new window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("FileLister") self.window.set_size_request(600, 400) self.window.connect("delete_event", self.delete_event) # TreeView self.treestore = gtk.TreeStore(str, gtk.gdk.Pixbuf, int, bool, str) self.treeview = gtk.TreeView(self.treestore) # TreeView Options self.treeview.set_level_indentation(0) self.treeview.set_show_expanders(True) # self.treeview.set_hover_expand(True) # self.treeview.set_search_column(0) # self.treeview.set_reorderable(True) # TreeViewColumns self.tvcolumn = [None] * len(self.column_names) cellpb = gtk.CellRendererPixbuf() self.tvcolumn[0] = gtk.TreeViewColumn(self.column_names[0], cellpb) self.tvcolumn[0].set_cell_data_func(cellpb, self.file_pixbuf) cell = gtk.CellRendererText() self.tvcolumn[0].pack_start(cell, False) self.tvcolumn[0].set_cell_data_func(cell, self.file_name) self.treeview.append_column(self.tvcolumn[0]) # Append more TreeView columns, if available for n in range(1, len(self.column_names)): cell = gtk.CellRendererText() self.tvcolumn[n] = gtk.TreeViewColumn(self.column_names[n], cell) if n == 1: cell.set_property('xalign', 0.0) self.tvcolumn[n].set_cell_data_func(cell, cell_data_funcs[n]) self.treeview.append_column(self.tvcolumn[n]) # Signals # self.treeview.connect('row-activated', self.on_row_activated) ''' FOLLOWING DOES NOT WORK ''' self.treeview.connect('row-has-child-toggled', self.on_row_activated) # Populate TreeView with initial files self.path = os.path.expanduser(DEFAULT_PATH) self.dir_walk(path=self.path, recurse=RECURSE) # Add scrolled Window self.scrolledwindow = gtk.ScrolledWindow() self.scrolledwindow.add(self.treeview) self.window.add(self.scrolledwindow) # Display the window self.window.show_all() # Populate TreeStore with directory listing def dir_walk(self, path, parent=None, recurse=0): filestat = os.stat(path) if not stat.S_ISDIR(filestat.st_mode): self.debug("File : "+path) return self.treestore for f in os.listdir(path): rec=recurse filename = os.path.join(path, f) fdata = os.stat(filename) is_folder = stat.S_ISDIR(fdata.st_mode) if is_folder: fType="Directory" hdr="%s: %s" % (fType, filename) else: fType="File" hdr="%s : %s" % (fType, filename) self.debug(hdr) img = gtk.icon_theme_get_default().load_icon( "folder" if is_folder else "document", gtk.ICON_SIZE_MENU, 0) try: ts = self.treestore.append(parent, [f,img,fdata.st_size, is_folder, path]) except Exception, error: ''' Note: exceptions occurs on certain files on Fedora-11 mounted NTFS filesystem <Needs investigating...> ''' extradata="Filename=%s\n%sFiletype=%s\n%sparent=%s, [f=%s, img=%s, size=%s, is_folder=%s, path=%s]" % (filename, SEP, fType, SEP, parent, f, img, fdata.st_size, is_folder, path) self.dump_traceback(extradata) continue if is_folder and rec > 0: rec=rec-1 self.dir_walk(path=filename, parent=ts, recurse=rec) return self.treestore def on_row_activated(self, treeview, path, column): model = treeview.get_model() iter = model.get_iter(path) filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) #self.debug("File : "+filename) ts = self.dir_walk(filename, parent=iter, recurse=1) treeview.set_model(ts) return def file_pixbuf(self, column, cell, model, iter): filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) filestat = os.stat(filename) if stat.S_ISDIR(filestat.st_mode): pb = gtk.icon_theme_get_default().load_icon("folder", gtk.ICON_SIZE_MENU, 0) else: pb = gtk.icon_theme_get_default().load_icon("document", gtk.ICON_SIZE_MENU, 0) cell.set_property('pixbuf', pb) return def file_name(self, column, cell, model, iter): cell.set_property('text', model.get_value(iter, 0)) return def file_size(self, column, cell, model, iter): filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) filestat = os.stat(filename) cell.set_property('text', filestat.st_size) return def file_mode(self, column, cell, model, iter): filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) filestat = os.stat(filename) cell.set_property('text', oct(stat.S_IMODE(filestat.st_mode))) return def file_last_changed(self, column, cell, model, iter): filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) filestat = os.stat(filename) cell.set_property('text', time.ctime(filestat.st_mtime)) return def file_path(self, column, cell, model, iter): filename = os.path.join(model.get_value(iter, 4), model.get_value(iter, 0)) cell.set_property('text', filename) return def debug(self, string): if DEBUG: print 'DEBUG: %s' % string def dump_traceback(self, extradata=None): import traceback etb = traceback.extract_tb(sys.exc_info()[2]) traceback = 'Traceback:\n' for tub in etb: f, l, m, c = tub # file, lineno, function, codeline traceback += ' '+('File: %(a)s, line %(b)s, in %(c)s\n') % {'a': f, 'b': l, 'c': m} traceback += ' %s \n' % c traceback += ' %s: %s' % (sys.exc_info()[0], sys.exc_info()[1]) #etype, evalue print "ERROR: Exception: %s\n%s%s" % (traceback, SEP, extradata) def main(): gtk.main() if __name__ == "__main__": myApp = FileLister() main() [/code] |