1

我用 Python 学习 GTK,但小部件有问题texview。我想更改/修改缓冲区 ( textview) 中文本的特定部分。

例如,文本缓冲区:

    long_text = "line 1 word 1 word 2 word 3 \n" \
                "line 2 [WORD TO REPLACE]  \n" \
                "line 3 \n"

[WORD TO REPLACE]我想用a 的值替换部分Gtk.Entry。我知道如何在缓冲区的末尾添加条目,但我无法从文本本身内部进行替换。

整个代码:

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)

欢迎任何想法。谢谢。

4

1 回答 1

0

这样做的方法是找到<WORD TO REPLACE>,删除它,然后在原来的地方输入新词<WORD TO REPLACE>

找词

要查找单词,您可以利用Gtk.TextIter'forward_search()方法。它需要两个参数:要查找的字符串和如何搜索(此参数必须是 的属性Gtk.TextSearchFlags)。我只是Gtk.TextSearchFlags.VISIBLE_ONLY用于这个,因为我不是在寻找不可见的东西。

self.text_buffer.get_start_iter().forward_search(
    "<WORD TO REPLACE>",
    Gtk.TextSearchFlags.VISIBLE_ONLY
)

删除单词

forward_search()方法返回一个包含两项的元组:单词的开始迭代器和单词的结束迭代器(除非它没有找到任何东西,在这种情况下它返回None;稍后会详细介绍)。这些迭代器非常方便,因为我们所要做的只是将它们传递给Gtk.TextBuffer'sdelete()方法。

start, end = i.forward_search("<WORD TO REPLACE>", Gtk.TextSearchFlags.VISIBLE_ONLY)
self.text_buffer.delete(start, end)

插入新词

您可以为此使用Gtk.TextBuffer'insert()方法。它需要三个参数:插入文本的迭代器、文本和文本的长度(您可以使用它-1来指定任何长度)。在这里,我使用self.entry.get_text()text 参数。

start, end = i.forward_search("<WORD TO REPLACE>", Gtk.TextSearchFlags.VISIBLE_ONLY)
self.text_buffer.delete(start, end)
self.text_buffer.insert(start, self.entry.get_text(), -1)

把它们放在一起

下面是整个update_textview()方法的样子:

def update_textview(self, widget):

    # Get the start iter of the textview
    i = self.text_buffer.get_start_iter()

    # Get the start and end index of <WORD TO REPLACE>
    search_result = i.forward_search("<WORD TO REPLACE>", Gtk.TextSearchFlags.VISIBLE_ONLY)

    # Make sure that the search actually found something
    if search_result is not None:
        start, end = search_result

        # Delete <WORD TO REPLACE>...
        self.text_buffer.delete(start, end)

        # ...and insert the text from the entry.
        self.text_buffer.insert(start, self.entry.get_text(), -1)

请注意,我使用它if search_result is not None来确保搜索确实找到了一些东西。如果此语句不存在,那么如果您单击按钮if但不存在,您会得到一个。TypeErrorUpdate<WORD TO REPLACE>

于 2021-11-12T21:07:17.073 回答