Search code examples
pythonpython-3.xgtkpygtkglade

Python3 gi: GtkTextBuffer core dump


Using Python3 with gi.repository.Gtk, I'm trying to display multiple text lines inside a GtkTextView via a GtkTextBuffer.

Basically, I'm dynamically adding lines using an _addLine method, which updates the text buffer that way (self._lines is an array and self._textBuffer is a GtkTextBuffer):

def _addLine(self, text):
    if len(self._lines) == self._maxLines:
        self._lines = self._lines[1:]
    self._lines.append(text)
    content = '\n'.join(self._lines)
    print("TIC: %d" % len(content))
    self._textBuffer.set_text(content)
    print("TAC")

Unfortunately, at random values of i (either lower or bigger than self._maxLines), I randomly get a core dump between "TIC" and "TAC", so when I try to set the content of the buffer.

This method is called by a threading, himself called from the constructor (after all the GUI elements are initialized):

def _startUpdateThread(self):
    thread = threading.Thread(target=lambda: self._updateLoop())
    thread.daemon = True
    thread.start()

def _updateLoop(self):
    i=0
    for l in listings.tail(self._logFile, follow=True, n=1000):
        i+=1
        print("i=%d, nLines=%d" % (i, len(self._lines)))
        self._addLine(l)

I'm using a Glade builder structured as below:

GtkWindow
  - GtkVBox
      - GtkScrolledWindow
          - GtkTextView (linked to GtkTextBuffer)
  - GtkButton (to close the window)
  - GtkTextBuffer

What did I do wrong? What is the cause of that core dump?

Thanks a lot for your help.


Solution

  • You should use GLib.idle_add() when you are modifying widgets from a thread and not the GTK main loop.

    In this case:

    GLib.idle_add(self._textBuffer.set_text, content)