Как автоматически прокручивать gtk.scrolledwindow?

У меня есть древовидный виджет внутри ScrolledWindow, который заполняется во время выполнения. Я хочу, чтобы ScrolledWindow автоматически прокручивался до конца списка. Я «решил» проблему, настроив vadjustment из ScrolledWindow каждый раз, когда строка вставляется в древовидную структуру. например:

if new_line_in_row:
   adj = self.scrolled_window.get_vadjustment()
   adj.set_value( adj.upper - adj.page_size )

Если я запускаю код в интерактивном сеансе ipython и сам устанавливаю значение, все работает так, как ожидалось.

Если я запускаю код с интерпретатором Python по умолчанию, автоматическая прокрутка не работает все время. Я отладил код, и проблема, похоже, в том, что значения настройки имеют некоторую «задержку» и изменяются только через определенный период времени.

Мой вопрос: как мне надежно прокрутить до максимальной позиции ScrolledWindow? генерируется специальный сигнал, который я могу использовать? или есть лучший способ установить adjustment-value?


person Fookatchu    schedule 07.03.2011    source источник
comment
Хороший вопрос. Я хотел знать это в течение долгого времени. Это вышло из этот вопрос, за который я даже предложил вознаграждение в размере 150, но не не получить ответ, на который я надеялся.   -  person ptomato    schedule 08.03.2011


Ответы (5)


После расширения радиуса поиска я нашел ответ, связанный с рубином. поскольку проблема связана с gtk, ее можно решить на любом языке следующим образом:

вы подключаете виджет, который изменяет, в моем случае древовидную структуру, с сигналом size-allocate gtk.widget и устанавливаете значение gtk.scrolledwindow в "upper - page_size". пример:

self.treeview.connect('size-allocate', self.treeview_changed)

...

def treeview_changed(self, widget, event, data=None):
    adj = self.scrolled_window.get_vadjustment()
    adj.set_value( adj.upper - adj.page_size )

ссылка на оригинальный пост на ruby-forum.com:

подсказка

person Fookatchu    schedule 08.03.2011
comment
переменные-члены теперь кажутся скрытыми. вместо этого используйте get_upper() и get_page_size() - person Fookatchu; 31.10.2013

Ответ fookatchu можно улучшить, чтобы обратный вызов мог использоваться несколькими виджетами:

def treeview_changed( self, widget, event, data=None ):
    adj = widget.get_vadjustment()
    adj.set_value( adj.upper - adj.pagesize )
person Chuck R    schedule 15.01.2012

Версия Python Gtk 3:

adj.set_value(adj.get_upper() - adj.get_page_size())

person Federico    schedule 16.12.2014
comment
Это не работает, например. a gtk.treeview: значения adj обновляются позже, поэтому в основном последняя добавленная строка не отображается. - person jcoppens; 13.07.2017

Все еще нужен обратный вызов (я использовал textView, а не treeView):

textView = Gtk.TextView()
scrolledWindow = Gtk.ScrolledWindow()

def textViewChanged( self, widget ):
    adjustment = scrolledWindow.get_vadjustment()
    adjustment.set_value( adjustment.get_upper() - adjustment.get_page_size() )

textView.connect( "size-allocate", textViewChanged )
person Bernmeister    schedule 25.04.2020

Принятый ответ помог мне найти решение Rust в gtk-rs для проблемы автоматической прокрутки до конца содержимого.

Вот фрагмент Rust, который может помочь другим:

// Imports used for reference
use gtk::{TextBuffer, TextView, TextBufferBuilder, ScrolledWindow, ScrolledWindowBuilder};

// The text buffer where the text is appended later
let text_buffer: TextBuffer = TextBufferBuilder::new().build();

// The containing text view that holds the text buffer
let text_view: TextView = TextView::new_with_buffer(&text_buffer);

// The scrolled window container with fixed height/width that holds the text view
let scrolled_window: ScrolledWindow = ScrolledWindowBuilder::new()
        .min_content_height(400)
        .min_content_width(600)
        .child(&text_view)
        .build();

// Have the text view connect to signal "size-allocate"
text_view.connect_size_allocate(clone!(@weak scrolled_window => move |_,_| {
   let adj = scrolled_window.get_vadjustment().unwrap();
   adj.set_value(adj.get_upper() - adj.get_page_size());
}));

// ...
// Later on, fill buffer with some text.
text_buffer.insert(&mut text_buffer.get_end_iter(), "This is my text I'm adding");
person ddubson    schedule 20.06.2020