> 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 [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/