我在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 / widgets已被修改。 必须使用标记,字符编号或行号来保留缓冲区修改的位置。 您可以应用标签并插入标记而不会使迭代器失效, 但是任何影响'可索引'缓冲区内容的变异(可以通过字符偏移引用的内容) 将使所有未完成的迭代器无效
Pango-CRITICAL **:pango_layout_index_to_pos:断言`layout!= NULL'失败
Gtk-WARNING **:gtktextview.c:4813:自上次验证屏幕上的行以来,某些文本行被修改或滚动 - 可能是文本小部件错误。
Gtk:错误:gtktextview.c:4814:gtk_text_view_paint:代码不应该到达
答案 0 :(得分:2)
要更新Gtk widgets from other threads,您需要:
一个。在调用 湾在您的主题中,使用以下代码包围更新Gtk小部件的代码: 在您的情况下,您可能需要以下内容:Gtk.main()
之前,请先调用以下方法
GObject.threads_init()
Gdk.threads_init()
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 :(得分:1)
如果您正在使用线程,就像您的评论中所看到的那样,根据我的经验,尝试更新线程中的小部件效果不佳。
此问题的解决方法是使用GLib.idle_add
计划更新窗口小部件的所有操作,以便在主线程中进行更新。