Отправляет email-рассылки с помощью сервиса Sendsay

Практические советы по GTK+

  Все выпуски  

Практические советы по GTK+ (Форматированный текст. часть 1)


Форматированный текст. часть 1

GTK содержит неплохую поддержку работы с форматированным текстом, можно даже с минимальными усилиями написать небольшой визуальный редактор rtf или html файлов. Разберёмся как всё работает с самого начала.

 

Создаём виджет  для вывода форматированного текста:

GtkWidget *text_view = gtk_text_view_new();

 

Для понимания работы с текстовым виджетом введём несколько понятий:

 

1)Все операции с текстом выполняются через текстовый буфер, который можно получить из виджета следующим образом:

GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));

2) Конкретное положение курсора в тексте определяется с помощью структуры GtkTextIter iter;

3) Форматирование текста задаётся при помощи тегов: GtkTextTag *tag;

 

Теперь непосредственно описание работы с текстовым виджетом:

 

Для добавления простого текста (без форматирования) можно сделать так:

GtkTextIter iter;

gtk_text_buffer_get_end_iter(buffer,&iter);// определяем положение в конце текстового буфера

gtk_text_buffer_insert(buffer,&iter,"New text",-1);// вставляем текст "New text" в конец буфера

 

Можно вставить текст в любое другое место, для этого нужно поставить другой iter,

Узнать iter по номеру столбца(y) и байта в строке(x): gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, y, x);

Узнать iter начала текстового буфера: gtk_text_buffer_get_start_iter(buffer,&iter);

Узнать iter конца текстового буфера: gtk_text_buffer_get_end_iter(buffer,&iter);

Определить выделенную область текста (от iter1 до iter2):

gtk_text_buffer_get_selection_bounds (text_buffer, &iter1, &iter2);

 

Можно наоборот, получить текст, между начальным и конечным iter-ами.

gchar *text = gtk_text_buffer_get_text(text_buffer,&start_iter,&end_iter,TRUE);

 

 

Для вставки форматированного текста можно воспользоваться функцией:

gtk_text_buffer_insert_with_tags(buffer,&iter,text,-1,tag1,tag2,tag3,0);

или по имени тега:

gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,text,-1,tag_name1,tag_name2,0);

Каждый тег определяет одно или несколько свойст форматирования (жирность, наклон, шрифт, цвет и т.д.), можно применять сразу несколько тегов, но после последнего должен стоять 0.

 

Предварительно тег должен быть создан:

Создать тег можно так:

GtkTextTag *tag = gtk_text_buffer_create_tag(buffer,tag_name, NULL);

g_object_set (tag,"weight",PANGO_WEIGHT_BOLD,NULL);// жирный шрифт

g_object_set (tag,"style",PANGO_STYLE_ITALIC,NULL);// установка наклонного шрифта

или сразу так:

GtkTextTag *tag = gtk_text_buffer_create_tag(buffer,tag_name,"weight",PANGO_WEIGHT_BOLD,"style",PANGO_STYLE_ITALIC,NULL);

tag_name - это имя тега, может быть любым, но только имена не должны повторяться, если имя не нужно, можно поставить NULL.

Полное описание всех возможных свойств тегов находится в официальной документации к GTK (в файле GtkTextTag.html), дабы не переписывать документацию, пропускаем эту часть.

 

 

Можно поменять форматирование у уже существующего текста:

gtk_text_buffer_apply_tag(text_buffer,tag,iter1,iter2);// применяем тег

А можно просто отменить действие конкретного тега на каком-то промежутке:

gtk_text_buffer_remove_tag_by_name(text_buffer,"bold",iter1,iter2);

 

 

Внимание! Только может получиться небольшая проблемка, когда на одном и том же месте текста применены взаимоисключающие теги, например шрифт "Sans Normal" и жирность текста weight=PANGO_WEIGHT_BOLD, при этом конфликтуют нормальная и повышенная жирность. Для решения таких проблем есть понятие приоритета тега, у кого он выше, то начертание и используется в спорном случае.

Функции для работы с приоритетами:

int prioritet = gtk_text_tag_set_priority(tag);// узнать приоритет тега (число от нуля и выше)

gtk_text_tag_set_priority(tag,prioritet);// установить новый приоритет тега

Для смены приоритета нужен указатель на GtkTextTag*, и если теги применяются по именам и GtkTextTag *tag не храниться, то тег из имени можно узнать следующим образом:

GtkTextTagTable *tag_table =  gtk_text_buffer_get_tag_table(buffer);// получить таблицу тегов

GtkTextTag *tag = gtk_text_tag_table_lookup(tag_table,tag_name);// ищем тег с именем tag_name

 

 

 

 

В текстовый виджет кроме текста можно вставлять картинки:

gtk_text_buffer_insert_pixbuf (buffer,&iter, pixbuf);

 

А также вставлять любые виджеты:

GtkTextChildAnchor *anchor;

anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);// создать якорь в заданном месте iter

widget = gtk_button_new_with_label("Это кнопка в тексте");// создать какой-нибудь виджет

gtk_text_view_add_child_at_anchor(text_view,widget,anchor);// поместить виджет в текстовое поле на место якоря

gtk_widget_show_all (widget);// отобразить виджет в текстовом поле

 

Хочется добавить, что в текстовом виджете можно подключать обработчики не только на стандартные операции, но и на каждый тег отдельно.

Напоследок скажу, что все выпуски можно найти в одном файле gtk_book.chm.



В избранное