Как определить точки итерации, чтобы изменить цвет определенной части текста, используя Gtk3 и виджет TextView? - PullRequest
0 голосов
/ 30 мая 2019

Я изменяю плагин Python для приложения музыкального плеера. Плагин отображает синхронизированные тексты песен, используя файлы lrc. Эти файлы имеют следующий формат для отображения строк в определенный момент времени:

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

Существует "улучшенная" версия файлов lrc, называемая elrc. Они одинаковы, за исключением того, что они могут содержать временные метки внутри строки, например:

[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. Я различаю их, чтобы вы могли увидеть, как плагин работал изначально.)

Переменные _lines и _words являются массивами, а их значения передаются в функцию "_show", которая затем отображает текст на экране с помощью TextView Gtk. Вот функция _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 использует только iters в качестве значений, чтобы определить раздел текста, который должен быть изменен, и я не могу найти способ сделать эти iters параметром «word». Помните, что большая часть этого кода не моя, а большая часть кода сильно лишена комментариев, поэтому я не понимаю, как это работает на 100%. Если вам нужно больше контекста, чтобы понять это, вы можете спросить меня, или вы можете проверить весь исходный код самостоятельно. Вы можете найти оригинальный неизмененный плагин здесь , и вы можете найти мою версию (немного устаревшую версию) плагина здесь .

...