【问题标题】:Gtk +3 TextView application crashesGtk +3 TextView 应用程序崩溃
【发布时间】:2016-06-13 01:43:22
【问题描述】:

我有一个使用 GtkTextView 和 GtkTextBuffer 的应用程序。使用以下 python 代码将行添加到缓冲区中,该代码在与主进程不同的线程中运行:

    while True:     
        if aLogQueue.qsize() > 0:
            aBuffer = aLogTextView.get_buffer()
            try:
                newLogMessage = aLogQueue.get_nowait()
                ipri = int(newLogMessage[0])                    
                if(ipri>=self.ListenLogMinPr):
                    aniter = aBuffer.get_iter_at_line(0)
                    aBuffer.insert(aniter, newLogMessage) 
                    #mark = aBuffer.get_mark('insert') 
                    #aniter = aBuffer.get_iter_at_mark(mark)
                    #aBuffer.place_cursor(aniter)
                pass
            except:
                print('threw exception in message loop')  
                self.gui_shutdown()  

aLogQueue 是单行 ASCII 文本消息的队列。

应用程序运行了一段时间,但随后总是崩溃并出现以下错误

Gtk:ERROR:gtktextview.c:4328:gtk_text_view_validate_onscreen: 断言失败:(priv->onscreen_validated)

请注意,我在第 0 行插入,因此迭代器被插入调用破坏的事实应该没有任何效果。

在失败之前它会写入 20 到 200 行。它似乎与注销文本缓冲区的边缘无关,并且滚动条按预期出现。

有什么建议吗?

【问题讨论】:

  • 感谢 RBT,但我需要更多信息。我有以下方法,它在 GTK 的单独线程中运行。

标签: python gtk gtktextview


【解决方案1】:

您不能从单独的线程访问 GtkTextBuffer — 或 GTK+ 的任何部分。您必须从 GUI 线程访问它。您将需要使用 GLib.idle_add() 在 GUI 线程上对缓冲区更新进行排队。

【讨论】:

    【解决方案2】:

    我对为 GLib 找到的文档感到困惑,因为 GLib.idle_add 不接受超时。 http://lazka.github.io/pgi-docs/index.html#GLib-2.0/functions.html#GLib.idle_add

    但没有超时,它对我使用 Python 2.7.12 和 Gtk 3.20 有效

    为文本插入创建函数

       def set_text(self, text):
        textbuffer = self.textview.get_buffer()
        textbuffer.set_text(text, len(text))
    
       def append_text(self, text:
        oldtext = self.get_text()
        newtext = "{}\n{}".format(oldtext, text)
        self.set_text(newtext)
    

    然后您可以设置新文本

    GLib.idle_add(self.textbox.append_text, "I am the new text line)  
    

    其他信息:

    在脚本运行时,我还检查按钮的灵敏度

    def on_search_button_clicked(self, widget)
        widget.set_sensitive(False)
        thread = Thread(target=self.run_search_script)
        thread.start()
        GObject.timeout_add(200, self.sensi, thread, widget)
    
    def sensi(self, thread, widget):
        return True if thread.is_alive() else widget.set_sensitive(True)
    

    【讨论】:

      猜你喜欢
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多