Как прикрепить всплывающее меню к кнопке заголовка столбца в GTK2 с помощью PyGObject? - PullRequest
6 голосов
/ 05 августа 2011

Я хочу открыть контекстное меню, когда пользователь щелкает правой кнопкой мыши строку заголовка Gtk.TreeView. В GTK3 Gtk.TreeViewColumn имеет метод get_button (), который делает это легко; просто прикрепите меню к кнопке и подключите его к событию «нажал». Однако в GTK2 это не сработает. Вы можете вызвать только метод get_widget(), который возвращает None, если вы не установили виджет через set_widget(). Я попытался поместить Gtk.Label с именем столбца в Gtk.EventBox и установить его в качестве виджета. После подключения EventBox к обратному вызову для button_press_event нажатие на него не генерирует событие.

Я пытался сделать что-то вроде того, что перечислено здесь , но выполнение get_parent() в виджете столбца возвращает None и никогда не достигает кнопки, как следует из их кода.

Какие решения нашли люди для этого?

Ответы [ 3 ]

3 голосов
/ 28 сентября 2011

На самом деле это довольно просто, но вам нужно несколько хаков.

Сначала вам нужно заставить Gtk создать кнопку заголовка для GtkTreeViewColumn:

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

После этого вынужно извлечь внутренний GtkButton заголовка:

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

Наконец, со ссылкой на кнопку вы можете сделать что-то полезное:

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

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

Это было взято из kiwi библиотека, которая имеет ObjectList , который предоставляет список python, такой как api для создания GtkTreeViews.

0 голосов
/ 04 января 2016

Мне нравятся рабочие примеры на SO, поэтому я решил опубликовать один.Все кредиты для @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()

счастливого взлома!

0 голосов
/ 16 сентября 2011

Это действительно кажется сложным, я взглянул на источник . Очевидно, уловка parent работает (и возвращает объект выравнивания), однако ваша пользовательская метка добавляется к кнопке только после того, как TreeviewColumn был реализован, так что до этого атрибут parent остается None Так что, вероятно, последний после вашего шоу Команда Treeview, вы должны быть в состоянии получить родителей (Button-> HBox-> Alignment-> Label) и можете прикрепить ваш обработчик к сигналу.

...