4

我有一个Gtk.ScrolledWindow()with inside a 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:断言“布局!= NULL”失败

Gtk-WARNING **: gtktextview.c:4813: 自上次验证屏幕上的行以来,不知何故修改了一些文本行或发生了滚动 - 可能是文本小部件错误。

Gtk:ERROR:gtktextview.c:4814:gtk_text_view_paint:代码不应到达

4

2 回答 2

3

要从其他线程更新Gtk 小部件,您需要:

一种。调用前调用以下方法Gtk.main()

GObject.threads_init()
Gdk.threads_init()

湾。在您的线程中,围绕更新 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()
于 2012-01-10T15:46:20.173 回答
1

根据我的经验,如果您正在使用线程,从您的评论中可以看出,尝试更新线程中的小部件效果不佳。

解决此问题的方法是安排更新小部件使用的所有操作,GLib.idle_add以便更新发生在主线程中。

于 2012-01-10T13:27:19.947 回答