Обзор виджета текста
Обзор виджета текста — Обзор GtkTextBuffer, GtkTextView и родственных элементов
Концептуальный обзор
GTK+ обладает чрезвычайно мощной системой для редактирования многострочного текста. Основные объекты, участвующие в этом процессе, это GtkTextBuffer, представляющий редактируемый текст, и GtkTextView, виджет, который может отображать GtkTextBuffer. Каждый буфер может быть отображен любым количеством представлений.
Важно помнить, что текст в GTK+ закодирован в UTF-8. Это означает, что один символ может быть закодирован несколькими байтами. Количество символов обычно называется смещениями, а количество байтов — индексами. Если вы перепутаете эти два понятия, всё будет работать нормально с ASCII, но как только ваш буфер будет содержать многобайтовые символы, возникнут проблемы.
Текст в буфере может быть помечен метками. Метка — это атрибут, который можно применить к некоторому диапазону текста. Например, метка может называться «жирный» и сделать текст внутри метки жирным. Однако понятие метки более общее; метки не обязательно влияют на отображение. Вместо этого они могут влиять на поведение нажатий мышью и клавиш, «заблокировать» диапазон текста, чтобы пользователь не мог его редактировать, или множество других вещей. Метка представлена объектом GtkTextTag. Одна метка GtkTextTag может быть применена к любому количеству диапазонов текста в любом количестве буферов.
Каждая метка хранится в GtkTextTagTable. Таблица меток определяет набор меток, которые можно использовать вместе. Каждый буфер имеет связанную с ним одну таблицу меток; только метки из этой таблицы могут быть использованы с буфером. Однако одну таблицу меток можно использовать для нескольких буферов.
Метки могут иметь имена, что иногда удобно (например, вы можете назвать свою метку, делающую вещи жирными, «жирный»), но они также могут быть анонимными (что удобно, если вы создаёте метки на лету).
Большинство манипуляций с текстом выполняется с помощью итераторов, представленных объектом GtkTextIter. Итератор представляет позицию между двумя символами в буфере текста. GtkTextIter — это структура, предназначенная для выделения на стеке; она гарантированно копируема по значению и никогда не содержит данных, выделенных в куче. Итераторы недействительны неопределённо; всякий раз, когда буфер изменяется таким образом, что это влияет на количество символов в буфере, все имеющиеся итераторы становятся недействительными. (Обратите внимание, что удаление 5 символов, а затем повторное вставка 5 символов всё равно делает итераторы недействительными, хотя в итоге у вас остаётся то же количество символов, но вы проходите через состояние с другим количеством).
Из-за этого итераторы нельзя использовать для сохранения позиций при модификациях буфера. Для сохранения позиции идеально подходит объект GtkTextMark. Вы можете рассматривать метку как невидимый курсор или точку вставки; она плавает в буфере, сохраняя позицию. Если текст вокруг метки удаляется, метка остаётся в позиции, которую занимал текст; если текст вставляется в метку, метка оказывается либо слева, либо справа от нового текста, в зависимости от её тяжести. Стандартный курсор текста в языках слева направо — это метка с правой тяжестью, потому что она остаётся справа от вставленного текста.
Как и метки, метки могут быть именованными или анонимными. В GtkTextBuffer есть две встроенные метки; они называются "insert" и "selection_bound" и относятся к точке вставки и границе выделения, которая не является точкой вставки соответственно. Если текст не выделен, эти две метки будут в одной позиции. Вы можете управлять выделением и местоположением курсора, перемещая эти метки.
Буферы текста всегда содержат по крайней мере одну строку, но могут быть пустыми (то есть буферы могут содержать ноль символов). Последняя строка в буфере текста никогда не заканчивается разделителем строк (например, новой строкой); остальные строки в буфере всегда заканчиваются разделителем строк. Разделители строк считаются символами при вычислении количества символов и смещений символов. Обратите внимание, что некоторые разделители строк Unicode представлены несколькими байтами в UTF-8, а последовательность из двух символов «\r\n» также считается разделителем строк.
Простой пример
Самое простое использование GtkTextView может выглядеть так:
Во многих случаях также удобно сначала создать буфер с помощью gtk_text_buffer_new(), а затем создать виджет для этого буфера с помощью gtk_text_view_new_with_buffer(). Или вы можете изменить буфер, отображаемый виджетом, после создания виджета с помощью gtk_text_view_set_buffer().
Пример изменения атрибутов текста
Существует два способа влияния на атрибуты текста в GtkTextView. Вы можете изменить стандартные атрибуты для данного GtkTextView, и вы можете применять метки, изменяющие атрибуты для области текста. Для текстовых функций, которые поступают от темы (таких как шрифт и цвет переднего плана), используйте стандартные функции GtkWidget, такие как gtk_widget_modify_font() или gtk_widget_override_color(). Для других атрибутов существуют специальные методы в GtkTextView, такие как gtk_text_view_set_tabs().
GtkWidget*view; GtkTextBuffer*buffer; view =gtk_text_view_new(); buffer =gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); gtk_text_buffer_set_text(buffer,"Hello, this is some text",-1); /* Now you might put the view in a container and display it on the * screen; when the user edits the text, signals on the buffer * will be emitted, such as "changed", "insert_text", and so on. */
Приложение gtk-demo, поставляемое с GTK+, содержит дополнительный пример кода для GtkTextView.
[2] Если вы хотите разместить курсор в ответ на действие пользователя, обязательно используйте gtk_text_buffer_place_cursor(), который перемещает их одновременно, не вызывая временного выделения (перемещение одного, а затем другого временно выделяет диапазон между старыми и новыми позициями).
© 2005–2020 The GNOME Project
Licensed under the GNU Lesser General Public License version 2.1 or later.
https://developer.gnome.org/gtk3/3.20/TextWidget.html