Приложение Gtk +3 TextView аварийно завершает работу

У меня есть приложение, использующее 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: ОШИБКА: gtktextview.c: 4328: gtk_text_view_validate_onscreen: утверждение не удалось: (priv-> onscreen_validated)

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

Он записывает от 20 до 200 строк перед сбоем. Похоже, это не связано с записью за край текстового буфера, и полосы прокрутки появляются, как и ожидалось.

Какие-либо предложения?


person Steve Ihnen    schedule 13.06.2016    source источник
comment
Спасибо RBT, но мне нужно больше информации. У меня есть следующий метод, который работает в отдельном потоке от GTK.   -  person Steve Ihnen    schedule 15.06.2016


Ответы (2)


Вы не можете получить доступ к GtkTextBuffer — или любой части GTK+, если уж на то пошло — из отдельного потока. Вы должны получить к нему доступ из потока GUI. Вам нужно будет использовать GLib.idle_add() для постановки в очередь обновления буфера в потоке GUI.

person andlabs    schedule 13.06.2016

Меня смутил документ, который я нашел для 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)
person oxidworks    schedule 26.04.2018