[pygtk] gtkspell breaks the TextView / accessing invalidated
iterators
Samuel Abels
newsgroups at debain.org
Mon Jul 7 06:22:13 WST 2008
Hi,
The following code works flawlessly when the gtkspell line is commented
out, and breaks when gtkspell is enabled.
----------------------
import gtk, gtkspell, locale
class Window(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.vbox = gtk.VBox()
self.hbox = gtk.HBox()
self.scroll = gtk.ScrolledWindow()
self.view = gtk.TextView()
buffer = self.view.get_buffer()
self.scroll.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self.set_size_request(600, 600)
self.vbox.set_border_width(6)
self.vbox.set_spacing(6)
self.hbox.set_spacing(6)
self.inserted = None
# Pack widgets.
self.scroll.add_with_viewport(self.view)
self.add(self.vbox)
self.vbox.pack_start(self.hbox, False)
self.vbox.pack_start(self.scroll)
self.show_all()
buffer.connect('insert-text', self._on_buffer_insert_text)
buffer.connect('changed', self._on_buffer_changed)
#gtkspell.Spell(self.view).set_language(locale.getlocale()[0])
def _on_buffer_insert_text(self, buffer, iter, text, length):
print "Inserted:", repr(text)
self.inserted = text, iter.get_offset()
def _on_buffer_changed(self, buffer):
if self.inserted is None:
return
print "Changed:", repr(self.inserted)
inserted, pos = self.inserted
self.inserted = None
if inserted == '#':
buffer.delete(buffer.get_iter_at_offset(pos),
buffer.get_iter_at_offset(pos + 1))
buffer.insert(buffer.get_iter_at_offset(pos), "X")
# Create widgets.
window = Window()
window.connect('delete-event', gtk.main_quit)
gtk.main()
----------------------
With gtkspell disabled, any time the "#" key is pressed an X is written
into the buffer.
With gtkspell enabled, the following output is generated:
------------------
GtkWarning: Invalid text buffer iterator: either the iterator is
uninitialized, or the characters/pixbufs/widgets in the buffer have been
modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a
position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that
can be referred to by character offset)
will invalidate all outstanding iterators
gtk.main()
show_text_view.py:50: GtkWarning: _gtk_text_buffer_get_line_log_attrs:
assertion `GTK_IS_TEXT_BUFFER (buffer)' failed
gtk.main()
show_text_view.py:50: GtkWarning: gtk_text_buffer_remove_tag: assertion
`gtk_text_iter_get_buffer (end) == buffer' failed
gtk.main()
show_text_view.py:50: GtkWarning: gtk_text_buffer_set_mark: assertion
`gtk_text_iter_get_buffer (iter) == buffer' failed
gtk.main()
Traceback (most recent call last):
File "show_text_view.py", line 50, in <module>
gtk.main()
------------------
It appears that gtkspell is trying to access an iterator that was
invalidated by manipulating the buffer in a callback. I tried to change
the buffer in different callbacks, such as insert-text, delete-range,
changed, but all of them break even when using connect_after().
Is this intended behavior, and if so, how do you manipulate the buffer
when spell-checking is enabled?
-Samuel
More information about the pygtk
mailing list