> The problem is the selected_foreach loop here. I'm pretty sure the
> issue is there's a discrepency between the references created by gtk
> and the python object references in this code path, so you end up with
> a path that references something gtk has dropped it's references to.
> 
> This is probably a PyGobject bug, but I'm not sure of all the details,
> so there may be a reason for the current behaviour.
> 
> You can avoid the issue by either expliticly copying the path in your
> selection_callback function - i.e, using pathlist.append(path.copy()),
> or by using the treeselection's get_selected_rows method.
> 

Thanks for the help.  Here is my modified code that works.  I used
treeselections's get_selected_rows.

Brent
#! /usr/bin/env python
''' Program to test the gi gtk interface.

'''

from gi.repository import Gtk, Gdk, GObject, Pango

def sync_selection(treeselection, other_treeview):
    ''' Synchronize the frozen column and the non-frozen columns.
    
    '''

    other_treeview.get_selection().select_iter(treeselection.get_selected()[1])

def quit_callback(widget):
    """Callback for file->quit menu item.
    
    """

    Gtk.main_quit()

def create_window():
    ''' Create a scrolled window.

    '''

    liststore = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
    for ii in range(20):
        liststore.append(['%d' % ii, 'row %d, col 1' % ii, 'row %d, col 2' % ii, ''])
    
    treeview = Gtk.TreeView(liststore)
    treeselection = treeview.get_selection()
    treeselection.set_mode(Gtk.SelectionMode.MULTIPLE)
    
    renderer = Gtk.CellRendererText()
    renderer.set_property('font-desc', Pango.FontDescription('Monospace Normal 10'))
    # Right justify the data.
    renderer.set_property('xalign', 1.0)

    col1 = Gtk.TreeViewColumn('Col 1', renderer, markup=1)
    col2 = Gtk.TreeViewColumn('Col 2', renderer, markup=2)

    treeview.append_column(col1)
    treeview.append_column(col2)
    # Add an extra column so the last column doesn't expand.
    treeview.append_column(Gtk.TreeViewColumn('', renderer, text=3))

    treeview.set_size_request(-1, 10)
    treeview.show()
    
    scrolled_window = Gtk.ScrolledWindow()
    scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
    scrolled_window.show()
    scrolled_window.add(treeview)

    return scrolled_window, treeselection

def selection_callback(model, path, select_iter, pathlist):
    '''Callback for selecting messages in the message list.

    '''
    pathlist.append(path)


def get_selected_rows_segfault(treeselection):
    '''Function to help with handling selections.

    '''
    
    pathlist = []
    treeselection.selected_foreach(selection_callback, pathlist)
    model = treeselection.get_tree_view().get_model()
    return (model, pathlist)

def get_selected_rows(treeselection):
    '''Function to help with handling selections.

    '''
    
    references = []
    model, paths = treeselection.get_selected_rows()
    for path in paths:
        references.append(Gtk.TreeRowReference.new(model, path))
    return model, references

class Test:
    ''' A class to test gi.

    '''

    ui = '''<ui>
    <menubar name="MenuBar">
      <menu action="File">
        <menuitem action="Quit"/>
        <menuitem action="Copy"/>
      </menu>
    </menubar>
    <popup name="Popup">
    </popup>
    <toolbar name="Toolbar">
    </toolbar>
    </ui>'''    

    def __init__(self):
        ''' Initialize a new Test instance.

        '''
        
        window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
        window.set_default_size(200, 200)
        window.show()

        box = Gtk.VBox(False, 0)
        box.show()
        window.add(box)

        uimanager = Gtk.UIManager()
        accelgroup = uimanager.get_accel_group()
        window.add_accel_group(accelgroup)
        actiongroup = Gtk.ActionGroup('UIManagerGiTest')
        actiongroup.add_actions([('Quit', Gtk.STOCK_QUIT, '_Quit', None,
                                  'Quit the Program', quit_callback),
                                 ('File', None, '_File'),
                                 ('Copy', Gtk.STOCK_COPY, '_Copy', None,
                                  'Copy selected messages in current tab', self.copy_callback)])

        uimanager.insert_action_group(actiongroup, 0)
        uimanager.add_ui_from_string(self.ui)
        menubar = uimanager.get_widget('/MenuBar')
        box.pack_start(menubar, False, True, 0)
        toolbar = uimanager.get_widget('/Toolbar')
        for n in range(0, toolbar.get_n_items()):
            toolbar.get_nth_item(n).set_is_important(True)
        box.pack_start(toolbar, False, True, 0)

        status_bar = Gtk.Statusbar()
        box.pack_end(status_bar, False, True, 0)
        context_id = status_bar.get_context_id("Statusbar")
        status_bar.push(context_id, "Welcome")

        status_bar.show()

        scrolled_window, self.treeselection = create_window()
        box.add(scrolled_window)

    def copy_callback_segfault(self, widget):
        """Callback for the copy menu item and toolbar item.
        
        """

        model, pathlist = get_selected_rows_segfault(self.treeselection)
        for selection in pathlist:
            selection_iter = model.get_iter(selection)
            print(model.get_value(selection_iter, 0))

    def copy_callback(self, widget):
        """Callback for the copy menu item and toolbar item.
        
        """

        model, references = get_selected_rows(self.treeselection)
        for ref in references:
            print(model.get_value(model.get_iter(ref.get_path()), 0))

    
    def main(self):
        ''' The main function.

        '''
        
        Gtk.main()
    
# The main program starts here.
        
if __name__ == '__main__':
    test = Test()
    test.main()
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to