I have an application I wrote using PyGTK that I recently converted
to use PyGobject introspection. When I try to do something with
selections in a TreeModel, I get a segmentation fault. The
corresponding pygtk code works. I have pared down my program to a
simple test case. I have included the pygtk version that works and the
PyGobject version that gives a segmentation fault. To see what I mean,
run the programs and select one or multiple rows then select File->copy
from the menu. Is this a PyGobject bug or am I doing something wrong?
#! /usr/bin/env python
''' Program to test the gi gtk interface.
'''
import gtk, 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.SELECTION_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.POLICY_AUTOMATIC, gtk.POLICY_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(treeselection):
'''Function to help with handling selections.
'''
pathlist = []
treeselection.selected_foreach(selection_callback, pathlist)
model = treeselection.get_tree_view().get_model()
return (model, pathlist)
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.WINDOW_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(self, widget):
"""Callback for the copy menu item and toolbar item.
"""
model, pathlist = get_selected_rows(self.treeselection)
for selection in pathlist:
selection_iter = model.get_iter(selection)
print(model.get_value(selection_iter, 0))
def main(self):
''' The main function.
'''
gtk.main()
# The main program starts here.
if __name__ == '__main__':
test = Test()
test.main()
#! /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(treeselection):
'''Function to help with handling selections.
'''
pathlist = []
treeselection.selected_foreach(selection_callback, pathlist)
model = treeselection.get_tree_view().get_model()
return (model, pathlist)
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(self, widget):
"""Callback for the copy menu item and toolbar item.
"""
model, pathlist = get_selected_rows(self.treeselection)
for selection in pathlist:
selection_iter = model.get_iter(selection)
print(model.get_value(selection_iter, 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/