[pygtk] TreeView selection issue
John Finlay
finlay at moeraki.com
Tue Jan 27 08:21:39 WST 2009
Alan F wrote:
> Hi
>
> I am new to GTK programming. I want to create a program that displays
> the sub-folders of a main folder in a tree view format. Once I find
> the particular sub-folder , I want to be able to click on it to
> display the contents of that folder. When the contents of that folder
> is displayed, I want to click on any file to display the mp3 tags of
> that file.
>
> I have managed to get a program working that displays all the
> sub-folders of the main folder as a treeview. The problem is I am
> having trouble trying to get it to do the next step i.e. when I click
> on a sub-folder I want to display the contents of that folder.
>
> After googling around, I found a post that used a solution of adding a
> button event to the treeview. I put it in an example code below and it
> works but with a problem.
>
> Firstly, to describe the actions of the example code, I've created a
> treeeview that has 3 parents and 3 childs, when I click on a selection
> (either parent or child), the value of that selection is printed in
> the console.
>
> The problem is that when I click on any selection, nothing happens.
> When I click on it again, the value of that selection is displayed.
> When I click on another selection, the value of the previous selection
> is displayed. When I click on that selection again, the values are
> displayed. On clicking on any selection, the value of the previous one
> is displayed.
>
> I've put console print statements throughout the code and the contents
> are definately being displayed when I single click on selection. I can
> only think it is something to do with the lines treeselection =
> self.treeview.get_selection(), (model, iter) =
> treeselection.get_selected().
>
> I've checked the API and in TreeSelection there is text that may have
> something to do my issue:
>
> "One of the important things to remember when monitoring the selection
> of a view is that the "changed" signal is mostly a hint. That is, it
> may only emit one signal when a range of rows is selected.
> Additionally, it may on occasion emit a "changed" signal when nothing
> has happened (mostly as a result of programmers calling the
> |select_path|()
> <file:///home/theman/documents/python/pygtkdoc/www.pygtk.org/docs/pygtk/class-gtktreeselection.html#method-gtktreeselection--select-path>
> or |select_iter|()
> <file:///home/theman/documents/python/pygtkdoc/www.pygtk.org/docs/pygtk/class-gtktreeselection.html#method-gtktreeselection--select-iter>
> methods on an already selected row)."
>
> I don't really know enough about GTK programming to understand where
> to start to look to fix this. Can someone please point me in the right
> direction?
>
>
> # #######Start of file
> #!/usr/bin/env python
>
>
> import pygtk
> pygtk.require('2.0')
> import gtk
> import os
>
> class BasicTreeViewExample:
>
> # close the window and quit
> def delete_event(self, widget, event, data=None):
> gtk.main_quit()
> return False
>
> def add_data(self):
>
> # we'll add some data now - 4 rows with 3 child rows each
> for parent in range(4):
> piter = self.treestore.append(None, ['parent %i' %
> parent, 'value %i' %parent])
> #print "this is path of parent " + str(parent)
> #print self.treestore.get_path(piter)
>
> for child in range(3):
> citr = self.treestore.append(piter, ['parent
> %i child %i' % (parent, child, ), 'value %i' %parent])
> #print "this is path of parent " + str(parent) + "child "
> + str(child)
> #print self.treestore.get_path(citr)
>
>
> def selectTest(self, widget, event):
> print "This is event button"
> print event.button
> # Mouse press confirmed ok
> if event.button == 1:
>
> #get data from highlighted selection
> treeselection = self.treeview.get_selection()
>
> (model, iter) = treeselection.get_selected()
> if iter != None :
> print "this is path of selected "
>
> print self.treestore.get_path(iter)
> print "value or select store"
> print self.treestore.get_value(iter, 0)
> print model.get_value(iter, 0)
>
> else:
> print "no selection made"
>
> def __init__(self):
> # Create a new window
> self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
>
> self.window.set_title("Music Collection")
>
> self.window.set_size_request(300, 200)
>
> self.window.connect("delete_event", self.delete_event)
>
> # create a new scrolled window.
> scrolled_window = gtk.ScrolledWindow()
> scrolled_window.set_border_width(10)
>
> # the policy is one of POLICY AUTOMATIC, or POLICY_ALWAYS.
> # POLICY_AUTOMATIC will automatically decide whether you need
> # scrollbars, whereas POLICY_ALWAYS will always leave the
> scrollbars
> # there. The first one is the horizontal scrollbar, the
> second, the
> # vertical.
> scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
> gtk.POLICY_ALWAYS)
>
> # The dialog window is created with a vbox packed into it.
> #self.window.vbox.pack_start(scrolled_window, True, True, 0)
> scrolled_window.show()
>
> # create a TreeStore with one string column to use as the model
> self.treestore = gtk.TreeStore(str, str)
> self.add_data()
>
> # create the TreeView using liststore
> self.treeview = gtk.TreeView(self.treestore)
> self.treeview.set_headers_visible(False)
>
> # create the TreeViewColumn to display the data
> self.tvcolumn = gtk.TreeViewColumn()
>
> # add tvcolumn to treeview
> self.treeview.append_column(self.tvcolumn)
>
> # create a CellRendererText to render the data
> self.cell = gtk.CellRendererText()
>
> # add the cell to the tvcolumn and allow it to expand
> self.tvcolumn.pack_start(self.cell, True)
>
> # set the cell "text" attribute to column 0 - retrieve text
> # from that column in treestore
> self.tvcolumn.add_attribute(self.cell, 'text', 0)
>
> # make it searchable
> self.treeview.set_search_column(0)
>
> self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
> self.treeview.connect('button_press_event', self.selectTest)
>
> # Allow sorting on the column
> #self.tvcolumn.set_sort_column_id(0)
>
> # Allow drag and drop reordering of rows
> self.treeview.set_reorderable(True)
>
> # pack the table into the scrolled window
> scrolled_window.add_with_viewport(self.treeview)
> self.window.add(scrolled_window)
> self.window.show_all()
>
> def main():
> gtk.main()
>
> if __name__ == "__main__":
> tvexample = BasicTreeViewExample()
> main()
>
> # #######End of file
Is there some reason why you are not using the TreeSelection "changed"
signal to track the selction changes and update your display? In your
case I assume that only one selection at a time is allowed so the
"changed" signal would seem to be ideal.
John
More information about the pygtk
mailing list