How do you connect a popup menu to a column header button in GTK2 using PyGObject?

I want to open the context menu when the user right-clicks the Gtk.TreeView title Gtk.TreeView . In GTK3, Gtk.TreeViewColumn has a get_button () method, which makes this simple; just attach the menu to the button and connect it to the 'clicked' event. However, in GTK2 this will not work. You can only call the get_widget() method, which returns None if you did not set the widget via set_widget() . I tried putting Gtk.Label with the column name in Gtk.EventBox and setting it as a widget. After connecting the EventBox to the callback for the button "button_press_event", clicking on it does not generate an event.

I tried to do something like what is indicated here , but when get_parent() executed, the column widget returns None and never reaches the button, as their code suggests.

What solutions did people find for this?

+6
source share
3 answers

It's pretty simple, but you need a few hacks.

First you need to get Gtk to create a header button for the GtkTreeViewColumn:

  label = gtk.Label("Column title") label.show() treeview_column.set_widget(label) 

After that, you need to get the internal GtkButton header:

  widget = treeview_column.get_widget() while not isinstance(widget, gtk.Button): widget = widget.get_parent() 

Finally, with a link to a button, you can do something useful:

  def button_release_event(button, event): if event.button == 3: menu.popup(event) widget.connect('button-release-event', button_release_event) 

This was taken from the kiwi library, which has an ObjectList that provides a python list such as api for creating GtkTreeViews.

+3
source

This is really complicated, I looked at source . Apparently the parent trick works (and returns an alignment object), however your custom shortcut is only added to the button after the TreeviewColumn has been implemented, so before that the parent attribute remains None So, probably the last after your Treeview show, you can get parents (Button-> HBox-> Alignment-> Label) and you can attach a handler to the signal.

0
source

I like working examples on SO, so I decided to publish them. All loans for @Johan Dahlin!

 #!/usr/bin/env python3 from gi.repository import Gtk def button_release_event(button, event): if event.button == 3: menu.popup(None, None, None, None, event.button, event.time) window = Gtk.Window() window.connect("destroy", lambda q: Gtk.main_quit()) liststore = Gtk.ListStore(str) liststore.append(["1"]) liststore.append(["2"]) menu=Gtk.Menu() menu.append(Gtk.ImageMenuItem("Yep it works!")) menu.append(Gtk.ImageMenuItem(":)")) menu.show_all() treeview = Gtk.TreeView(model=liststore) window.add(treeview) treeviewcolumn = Gtk.TreeViewColumn() treeview.append_column(treeviewcolumn) # Set the treeviewcolum as clickable # treeviewcolumn.set_clickable(True) # force Gtk to create a header button for the Gtk.TreeViewColumn # label = Gtk.Label("Numbers") label.show() treeviewcolumn.set_widget(label) # fetch the internal GtkButton of the header: # widget = treeviewcolumn.get_widget() while not isinstance(widget, Gtk.Button): widget = widget.get_parent() widget.connect('button-release-event', button_release_event) cellrenderertext = Gtk.CellRendererText() treeviewcolumn.pack_start(cellrenderertext, True) treeviewcolumn.add_attribute(cellrenderertext, 'text', 0) window.show_all() Gtk.main() 

happy hack!

0
source

Source: https://habr.com/ru/post/894401/


All Articles