Надеюсь, вы не возражаете, я использую GTK + C API в описании, решение может быть легко преобразовано в PyGTK, и принципы остаются прежними.
Начиная со второго вопроса - если вы знаете, какой виджет тестировать, вы можете определить его видимость, вызвав gtk_widget_translate_coordinates(child, parent, 0, 0, &x, &y)
, чтобы узнать положение дочернего элемента относительно родительского.По gtk_widget_get_allocation()
вы получаете размер родительского и дочернего элементов и просто проверяете, находится ли весь дочерний прямоугольник в прокручиваемом окне.
gboolean is_visible_in (GtkWidget *child, GtkWidget *scrolled)
{
gint x, y;
GtkAllocation child_alloc, scroll_alloc;
gtk_widget_translate_coordinates (child, scrolled, 0, 0, &x, &y);
gtk_widget_get_allocation(child, &child_alloc);
gtk_widget_get_allocation(scrolled, &scroll_alloc);
return (x >= 0 && y >= 0)
&& x + child_alloc.width <= scroll_alloc.width
&& y + child_alloc.height <= scroll_alloc.height;
}
Вы можете получить виджет, сфокусированный в окне, с помощью gtk_window_get_focus ()
или выможет обнаружить его при изменении фокуса.
В задаче автоматической прокрутки вы можете обрабатывать сигнал "focus"
, подключенный к виджету, который может быть сфокусирован, или событие "set-focus-child"
, подключенное к контейнеру, содержащему виджеты.В обработчике сигналов вы должны проверить, виден ли сфокусированный виджет.Если нет, определите его положение и правильно прокрутите.
Для этого вы должны определить положение виджета внутри всей области прокрутки.Если вы используете какой-то контейнер, который не поддерживает прокрутку (например, GtkHBox
), то есть GtkScrolledWindow
(адаптировано для области просмотра), вы можете получить координаты сфокусированного виджета относительно контейнера снова gtk_widget_translate_coordinates()
- теперь используя контейнервместо прокручиваемого окна.Значение регулировки, если используется GtkViewport
, значение регулировки соответствует позиции в пикселях в прокручиваемой области, поэтому при установке значения регулировки на относительную координату x будет выполняться прокрутка.Таким образом, важной частью обработчика может быть
GtkWidget *scrolled = /* The scrolled window */
GtkWidget *container = /* The container in the scrolled window */
GtkWidget *focused = /* The focused widget */
GtkAdjustment *hadj = gtk_scrolled_window_get_hadjustment(
GTK_SCROLLED_WINDOW(scrolled));
gint x, y;
gtk_widget_translate_coordinates (focused, container, 0, 0, &x, &y);
gtk_adjustment_set_value(hadj, min(x, maximal adjustment value allowed);
Максимально допустимое значение корректировки - Adjustment.upper - Adjust.page_size.Сфокусированный виджет передается в качестве аргумента обработчика сигнала для обоих сигналов, в случае сигнала "set-focus-child"
вы также получаете контейнер в качестве аргумента.