I learn GTK with Python and I've a problem with the widget texview.
I'd like to changed / modify specific part of a text in a buffer (textview).
For example, the text buffer:
long_text = "line 1 word 1 word 2 word 3 \n" \
"line 2 [WORD TO REPLACE] \n" \
"line 3 \n"
I 'd to replace the section [WORD TO REPLACE] by the value of a Gtk.Entry.
I know how to add the entry a the end of the buffer, but I'm not able to replace from inside the text itself.
The entire code:
from gi.repository import Gtk
import sys
class MyWindow(Gtk.ApplicationWindow):
def __init__(self, app):
Gtk.Window.__init__(self, title="TextView Example", application=app)
self.set_default_size(300, 450)
# a scrollbar for the child widget (that is going to be the textview)
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_border_width(5)
# we scroll only if needed
scrolled_window.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolled_window.set_min_content_height(400)
scrolled_window.set_min_content_width(400)
# a text buffer (stores text)
self.text_buffer = Gtk.TextBuffer()
#Test texte
long_text = "line 1 word 1 word 2 word 3 \n" \
"line 2 <WORD TO REPLACE> \n" \
"line 3 \n"
# a textview (displays the buffer)
self.textview = Gtk.TextView(buffer=self.text_buffer)
# wrap the text, if needed, breaking lines in between words
self.textview.set_wrap_mode(Gtk.WrapMode.WORD)
self.text_buffer = self.textview.get_buffer()
self.text_buffer.insert_at_cursor(long_text)
# textview is scrolled
scrolled_window.add(self.textview)
self.entry=Gtk.Entry()
self.entry.set_text("Entry")
btnUpdate = Gtk.Button(label="Update")
btnUpdate.connect("clicked", self.update_textview)
grid = Gtk.Grid()
grid.attach(self.entry,0,1,1,1)
grid.attach(btnUpdate,0,2,1,1)
grid.attach(scrolled_window,0,3,1,1)
self.add(grid)
def update_textview(self, widget):
self.text_buffer.insert_at_cursor(self.entry.get_text() + '\n')
class MyApplication(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
win = MyWindow(self)
win.show_all()
def do_startup(self):
Gtk.Application.do_startup(self)
app = MyApplication()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
Any idea is welcome. Thanks.
The way to do this is to find
<WORD TO REPLACE>, delete it, and type in the new word at the place where<WORD TO REPLACE>was.Finding the word
To find a word, you can take advantage of
Gtk.TextIter'sforward_search()method. It requires two arguments: the string to find, and the how to search (this argument has to be an attribute ofGtk.TextSearchFlags). I just useGtk.TextSearchFlags.VISIBLE_ONLYfor this, because I'm not searching for something that's not visible.Deleting the word
The
forward_search()method returns a two-item tuple: the word's start iter and the word's end iter (unless it doesn't find anything, in which case it returnsNone; more on that in a bit). These iters come in very handy, because all we have to do is simply pass them along toGtk.TextBuffer'sdelete()method.Inserting the new word
You can use
Gtk.TextBuffer'sinsert()method for this. It takes three arguments: the iter at which to insert the text, the text, and the length of the text (you can just use-1to specify any length). Here I useself.entry.get_text()for the text argument.Putting it all together
Here is what the entire
update_textview()method should look like:Note that I use
if search_result is not Noneto make sure that the search actually found something. If thisifstatement wasn't there, you would get aTypeErrorif you clicked the Update button and<WORD TO REPLACE>wasn't there.