Gtk + 3 - Проблемы с написанием и автопрокруткой в ​​TextView - PullRequest
3 голосов
/ 10 января 2012

У меня Gtk.ScrolledWindow() внутри Gtk.TextView(), (я использую интроспекцию PyGObject).

После того, как я вставил текст и произвел автопрокрутку из другого потока, несколько раз вызывая методappend_text, я получаю пару предупреждений, а затем GUI падает.

Это неприятная часть моего кода:

class TextViewWindow(Gtk.Window):

    [...]

    def append_text(self, text):
        self.textbuffer.insert(self.textbuffer.get_end_iter(), text)
        self.scroll_to_end()

    def scroll_to_end(self):
        self.textbuffer.place_cursor(self.textbuffer.get_end_iter())
        insert_mark = self.textbuffer.get_insert()
        self.textview.scroll_to_mark(insert_mark , 0.0, True, 0.0, 1.0)

Кто-нибудь знает, что я делаюнеправильно?

-
Вот некоторые из ошибок, которые я получил:

Gtk-WARNING **: Неверный итератор текстового буфера: либо итераторнеинициализированы, или символы / pixbufs / виджеты в буфере были изменены с момента создания итератора.Вы должны использовать метки, номера символов или номера строк, чтобы сохранить положение между изменениями буфера.Вы можете применять теги и вставлять метки, не делая недействительными ваши итераторы, но любая мутация, которая влияет на «индексируемое» содержимое буфера (содержимое, на которое можно ссылаться смещением символов), сделает недействительными все ожидающие итераторы

Pango-CRITICAL **:pango_layout_index_to_pos: утверждение `layout! = NULL 'не удалось

Gtk-WARNING **: gtktextview.c: 4813: каким-то образом были изменены некоторые текстовые строки или произошла прокрутка с момента последней проверки строк на экране - это может бытьошибка текстового виджета.

Gtk: ОШИБКА: gtktextview.c: 4814: gtk_text_view_paint: код не должен быть достигнут

Ответы [ 2 ]

2 голосов
/ 10 января 2012

Чтобы обновить Gtk виджеты из других потоков , вам необходимо:

a.Вызовите следующие методы до , по которому вы звоните Gtk.main()

GObject.threads_init()
Gdk.threads_init()

b.В вашей теме окружите код, который обновляет виджеты Gtk:

Gdk.threads_enter()
# your code here
Gdk.threads_leave()

В вашем случае вам, вероятно, понадобится что-то вроде:

Gdk.threads_enter()
your_window.append_text('something')
your_window.scroll_to_end()
Gdk.threads_leave()
1 голос
/ 10 января 2012

Если вы используете потоки, как видно из ваших комментариев, по моему опыту, попытка обновить виджеты в потоках не работает хорошо.

Обходной путь к этой проблеме - запланируйте все действия, которые обновляют виджеты, используя GLib.idle_add, чтобы обновление происходило в главном потоке.

...