Has anyone been able to force TreeView expander with no children?

View: New views
7 Messages — Rating Filter:   Alert me  

Has anyone been able to force TreeView expander with no children?

by Daniel B. Thurman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I have a FileViewer application that I am working on
and so far I have not been able to force expanders
on TreeView when there are only "top-level"
directories/files populated in the TreeStore.

You would think that doing something simple as:
[...]
self.treestore = gtk.TreeStore(str, gtk.gdk.Pixbuf, str)
self.treeview = gtk.TreeView(self.treestore)
self.treeview.set_show_expanders(True)
self.path = os.path.expanduser('~')
self.populate_treestore(path=self.path, recurse=0)
[...]

Would force the TreeView to show the expanders,
but I have not been able to get this to work.  I need
the expanders so that when I expand the directory
in question, I would then trigger a call to add more
children, and so on.

Any ideas?

Thanks-
Dan

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Has anyone been able to force TreeView expander with no children?

by Shaun McCance-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 2009-10-14 at 18:52 -0700, Daniel B. Thurman wrote:

> I have a FileViewer application that I am working on
> and so far I have not been able to force expanders
> on TreeView when there are only "top-level"
> directories/files populated in the TreeStore.
>
> You would think that doing something simple as:
> [...]
> self.treestore = gtk.TreeStore(str, gtk.gdk.Pixbuf, str)
> self.treeview = gtk.TreeView(self.treestore)
> self.treeview.set_show_expanders(True)
> self.path = os.path.expanduser('~')
> self.populate_treestore(path=self.path, recurse=0)
> [...]
>
> Would force the TreeView to show the expanders,
> but I have not been able to get this to work.  I need
> the expanders so that when I expand the directory
> in question, I would then trigger a call to add more
> children, and so on.

If you want to populate data on-demand like this,
you're probably going to have to write your own
GtkTreeModel.

--
Shaun


_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Has anyone been able to force TreeView expander with no children?

by Holger Berndt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Daniel,

On Mi, 14.10.2009 18:52, Daniel B. Thurman wrote:

>I need
>the expanders so that when I expand the directory
>in question, I would then trigger a call to add more
>children, and so on.

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.

Holger
_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Parent Message unknown Re: Has anyone been able to force TreeView expander with no children?

by Daniel B. Thurman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 10/15/2009 09:36 AM, Holger Berndt wrote:

> Hi Daniel,
>
> On Mi, 14.10.2009 18:52, Daniel B. Thurman wrote:
>
>  
>> I need
>> the expanders so that when I expand the directory
>> in question, I would then trigger a call to add more
>> children, and so on.
>>    
> 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.
>
> Holger
>  
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=None):
        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]

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Has anyone been able to force TreeView expander with no children?

by Holger Berndt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 15 Oct 2009 10:04:35 -0700 Daniel B. Thurman wrote:

> The problem I have is: how do I capture the signal when the
> row is expanded?  

GtkTreeView has a "row-expanded" signal.

> I sure wish there is a Python-GTK code somewhere
> that I could peruse to resolve my many issues!

I was using the technique that I described before for a small script
that offers a journaled view on the trash, see
http://github.com/hb/trashjournal/blob/3dc901a15490b3f5bc77a5be3f42ed4ff8b784ad/trashjournal.py
I blogged about it (the script in general, not the treeview technique)
here:
http://berndth.blogspot.com/2009/07/trashjournal-your-friendly-desktop.html

Holger
_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Has anyone been able to force TreeView expander with no children?

by Daniel B. Thurman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@... (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=None):
        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]




_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Has anyone been able to force TreeView expander with no children?

by David Nečas (Yeti)-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 15, 2009 at 10:25:23AM -0700, Daniel B. Thurman wrote:
> (1) The signal is called "row-expanded".
>
> [Dan] Thank you!  But how did you find this signal?

I know about it.  However, if I didn't I would go to

http://library.gnome.org/devel/gtk/stable/GtkTreeView.html#GtkTreeView.signals

or the same in devhelp assuming I have the API docs installed, or to the
gtk.TreeView docs for Python.  They all list all the signals.

Yeti


P.S.: Please don't cross-post though at this moment it is too late to
stop it in this thread...
_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list