API развился с тех пор, как был задан этот вопрос, поэтому я решил опубликовать обновленный ответ.(Я наткнулся на это, когда сталкивался с подобной проблемой, хотя в моем случае я пытался поместить две кнопки в заголовок столбца, а не запись.)
Сначала немного фона.Как упомянуто в редактировании вопроса, проблема связана со структурой TreeViewColumn.Заголовок столбца - это кнопка, и когда вы set_widget
, этот виджет становится потомком кнопки.(Это может быть легко пропущено, поскольку заголовок не реагирует как кнопка, если вы не установите для столбца возможность щелкать мышью. Кроме того, документация не помогает, так как кажется, что все это уже знают.) Еще одна причина проблемыКак кнопки собирать события.В отличие от большинства виджетов, отвечающих на события, у кнопки нет своего места в иерархии Gdk.Window.Вместо этого он создает специальное окно события, когда оно реализовано.Метод доступа к этому окну зависит от кнопки: get_event_window
(отличается от более общих get_window
и get_parent_window
).Это окно событий незаметно расположено над кнопкой, собирая события, прежде чем они перейдут к потомкам кнопки.Следовательно, виджет, который вы помещаете в заголовок столбца, не получает события, необходимые для интерактивности.
Принятое решение является одним из способов обойти это препятствие, и в то время это был достойный ответ.Однако теперь есть более простой способ.(Я должен отметить, что это проблема GTK +, независимо от используемой языковой привязки. Лично я использовал привязку C ++. Я также посмотрел на исходные файлы GTK + - в C -, чтобы подтвердить, что это основное поведение GTK +, а ненекоторый артефакт привязки.)
1) Найдите заголовок Button.
Если column
- это рассматриваемый TreeViewColumn, API для получения кнопки теперьпросто:
header_button = column.get_button()
Метод get_button
был добавлен в версию 3.0, которая была помечена примерно через шесть месяцев после того, как был задан этот вопрос.Настолько близко.
2) Распространение событий от Кнопки до входа.
Потребовалось еще четыре года (версия 3.18) для упрощения этого шага.Ключевая разработка была set_pass_through
, которая может указывать окну событий пропускать события.Как говорится в документации: «В терминологии сети это будет называться« указатель-события: нет ».»
def pass_through_event_window(button, event):
if not isinstance(button, gtk.Button):
raise TypeError("%r is not a gtk.Button" % button)
event_window = button.get_event_window()
event_window.set_pass_through(True)
Остальная уловка связана с синхронизацией.Окно событий не создается до тех пор, пока кнопка не будет реализована, поэтому подключение к сигналу кнопки realize
осуществляется по порядку.
header_button.connect('realize', pass_through_event_window)
И все (шаг 3 отсутствует).События теперь будут распространяться на Entry или любой виджет, который вы поместите в заголовок столбца.
Мои извинения, если я испортил синтаксис;Я перевожу с привязки C ++.Если есть ошибки, я бы попросил любезного гуру Python исправить их.