如何使用Gtk3和TextView小部件定义迭代点以更改文本特定部分的颜色?

2024-06-14 05:05:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在修改音乐播放器应用程序的python插件。该插件使用lrc文件显示同步歌词。这些文件具有以下格式以在给定时间显示行:

[00:02.32]Some lyric
[00:03.21]More lyrics
[00:05.76]You get the point by now

有一个名为elrc的lrc文件的“改进”版本。它们是相同的,只是它们可以在一行中包含时间戳,如下所示:

[00:02.32]Some lyric <00:02.98>something else is shown here
[00:03.21]More lyrics <00:04.21>even more lyrics <00:05.21>maybe two of these
[00:05.76]You get the point by now x2

我修改了插件,使其支持elrc文件。我想这样做的方法是,每当遇到一个时间戳,就改变文本的颜色,但是应该改变的文本区域必须在下一个时间戳停止。因此,如果每个单词都有时间戳,那么文本的颜色会在正确的时间逐字改变

该插件的工作方式是使用时间戳和单词/行的二维数组

def _set_timers(self):
    print_d("Setting timers")
    if len(self._timers) == 0:
        cur_time = self._cur_position()
        cur_idx = self._greater(self._lines, cur_time)
        if cur_idx != -1:
            while (cur_idx < len(self._lines) and
                   self._lines[cur_idx][0] < cur_time + self.SYNC_PERIOD):

                timestamp = self._lines[cur_idx][0]
                line = self._lines[cur_idx][1]
                #word = self._words[cur_idx][1]
                tid = GLib.timeout_add(timestamp - cur_time, self._show, line, #word)
                self._timers.append((timestamp, tid))
                cur_idx += 1

(标有“#”的行和参数是我为使插件支持elrc文件而添加的行。我将它们区分开来,以便您可以看到插件最初是如何工作的。)

_line和_words变量是数组,它们的值被传递给“_show”函数,然后该函数使用Gtk的TextView在屏幕上显示歌词。以下是_show函数:

def _show(self, line, word):
    self.text_buffer.set_text(line)
    #startIter = self.text_buffer.get_start_iter()
    #endIter = self.text_buffer.get_end_iter()
    #color = self.text_buffer.create_tag("highlight", foreground=self._highlight_text())
    #self.text_buffer.apply_tag(color, startIter, endIter)
    self._start_clearing_from += 1
    print_d("♪ %s ♪" % line.strip())
    return False

与前面一样,我用“#”标记的行是我添加的支持elrc标记的行(因此,逐字显示)。我遇到的问题是,“apply_tag”方法只使用iter作为值来定义必须更改的文本部分,我无法找到将这些iter作为“word”参数的方法。请记住,这段代码大部分不是我写的,而且大部分代码严重缺乏注释,因此我无法100%理解它是如何工作的。如果您需要更多的上下文来理解这一点,您可以问我,或者您可以自己检查整个源代码。您可以找到原始的未修改插件here,也可以找到插件here的我的版本(稍微过时的版本)


Tags: 文件text文本self插件gettimebuffer