Reputation: 46
I created a custom widget inheriting from Gtk.CellRenderer
, where I define a custom signal which I emit from the overridden do_active
. When I try to show a Gtk.Popover
with popup()
in the connected handler method for that signal, I get a segmentation fault (core dumped).
The signal seems to work alright, all the data is passed and everything. It's only when I try to show a new widget here that this happens. Creating Popovers works from other methods.
Same thing happens if I try to show Gtk.Dialog
, but much less commonly - it happens every other time or so, while with Gtk.Popover
it happens 95% of the time.
class MyCellRenderer(Gtk.CellRenderer):
__gproperties__ = { ... }
__gsignals__ = {
'clicked': (
GObject.SignalFlags.RUN_FIRST,
None,
( ... )
)
}
def __init__(self):
...
def do_activate(self, event, widget, path, background_area, cell_area, flags):
...
self.emit('clicked', path, key, rect)
...
class AppWindow(Gtk.ApplicationWindow):
def __init__(self, application):
...
my_renderer = MyCellRenderer()
my_renderer.connect('clicked', self.on_renderer_clicked)
...
my_treeview_column = Gtk.TreeViewColumn('My Renderer')
my_treeview_column.pack_start(my_renderer, True)
my_treeview_column.add_attribute( ... )
...
self.treeview.append_column(my_treeview_column)
...
def on_renderer_clicked(self, *args):
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label = Gtk.Label(label='Example label')
box.pack_start(label, True, True, 10)
box.show_all()
popover = Gtk.Popover()
popover.add(box)
popover.set_relative_to(self.treeview) # any widget would give the same result
popover.popup() # segmentation fault happens here
...
I know this used to work, as I have tested it before. Coming back to the (unmodified) code after some time, I am surprised to see such an issue. Could it be a bug in the newer version of some of the imported modules? If so, which one? Any ideas for troubleshooting?
Upvotes: 0
Views: 77
Reputation: 46
Being unable to find the real reason behind the segfault, I had to take a different approach to achieve what I initially wanted. I decided to ditch the custom signal, and instead try to catch events on the Treeview
, and from here to then get the information I need.
This might, in fact, be the preferred way of showing Popover
widgets over Treeview
in PyGtk, but I cannot confirm as I couldn't find any examples of it.
The code from the example above would now look like this:
class MyCellRenderer(Gtk.CellRenderer):
__gproperties__ = { ... }
def __init__(self):
...
# custom signal is removed
# so is do_activate() as there is no need for CellRenderer to be activatable any more
class AppWindow(Gtk.ApplicationWindow):
def __init__(self, application):
...
my_renderer = MyCellRenderer()
# we connect the 'button-press-event' signal now
my_renderer.connect('button-press-event', self.on_treeview_clicked)
...
my_treeview_column = Gtk.TreeViewColumn('My Renderer')
my_treeview_column.pack_start(my_renderer, True)
my_treeview_column.add_attribute( ... )
...
self.treeview.append_column(my_treeview_column)
...
def on_treeview_clicked(self, widget, event):
# process only left click events
if event.button == 1:
# find the path and column at the point of click event
path, column, cell_x, cell_y = widget.get_path_at_pos(int(event.x), int(event.y))
# process only valid, selected paths for our desired column (index 1 in this example)
if path is not None and column == widget.get_column(1) and widget.get_selection().path_is_selected(path):
# get coordinates for clicked cell
cell_area = widget.get_cell_area(path, column)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label = Gtk.Label(label='Example label')
box.pack_start(label, True, True, 10)
box.show_all()
popover = Gtk.Popover()
popover.add(box)
popover.set_relative_to(widget)
# set popover to point to clicked cell
popover.set_pointing_to(cell_area)
popover.popup()
...
Upvotes: 0