2011-08-05 17 views
6

Quiero mostrar un menú contextual cuando el usuario hace clic con el botón derecho en la fila del encabezado de Gtk.TreeView. En GTK3, Gtk.TreeViewColumn tiene un método get_button(), que lo hace fácil; simplemente conecte el menú al botón y conéctelo a un evento "hecho clic". Sin embargo, en GTK2, esto no funcionará. Solo puede llamar al método get_widget(), que devuelve None si no ha configurado un widget a través del set_widget(). Intenté poner un Gtk.Label con el nombre de columna en Gtk.EventBox y configurarlo como el widget Después de conectar el EventBox a una devolución de llamada para el 'button_press_event', al hacer clic en él no se genera el evento.¿Cómo se adjunta un menú emergente a un botón de encabezado de columna en GTK2 utilizando PyGObject?

Intenté hacer algo como lo que figura en la lista here pero al hacer get_parent() en la columna, el widget devuelve None y nunca llega al botón como lo indica su código.

¿Qué soluciones han encontrado las personas para esto?

+0

Debo aclarar que por "en GTK2, esto no funcionará", debería haber dicho, "en GTK2, el método' get_button() 'no se implementó. –

+0

Ahora también estoy descubriendo que' menu.attach_to_widget() 'y' menu.popup() 'aparentemente no son introspectibles en GTK2. Según el [sitio PyGObject] (https://live.gnome.org/PyGObject/IntrospectionPorting), en GTK3' menu.popup() 'se implementó a través de una anulación, sin embargo, no puedo encontrar documentación sobre cómo se hizo esto. –

Respuesta

3

Esto es bastante fácil en realidad, pero necesita un par de hacks.

primer lugar usted necesita para forzar GTK para crear un botón de cabecera para la GtkTreeViewColumn:

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

Después de que usted tendrá que obtener el GtkButton interna de la cabecera:

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

último con un botón referencia puede hacer algo útil:

def button_release_event(button, event): 
     if event.button == 3: 
      menu.popup(event) 

    widget.connect('button-release-event', button_release_event) 

Esto fue tomado del kiwi biblioteca que tiene un ObjectList que proporciona una lista de python como api para crear GtkTreeViews.

+0

Escribo en Perl, pero este mismo enfoque funciona. ¡Gracias! De nota, tengo que agregar la columna a la vista de árbol antes de llamar a get_widget. – TheAmigo

0

Esto de hecho parece complicado, eché un vistazo a source. Aparentemente, el truco parent funciona (y devuelve el objeto de alineación); sin embargo, su etiqueta personalizada solo se agrega al botón después de que TreeviewColumn se haya realizado, por lo que antes el atributo parent permanece None Probablemente sea lo último después del comando show de Treeview, debería ser capaz de recuperar los padres (Button-> HBox-> Alignment-> Label) y puede conectar su controlador a la señal.

0

Me encantan los ejemplos de trabajo en S.O., así que decidí publicar uno. ¡Todos los créditos son para @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 hacking!

Cuestiones relacionadas