Преобразовать строку разметки Панго в свойства GtkTextTag - PullRequest
0 голосов
/ 18 марта 2012

У меня есть gtk.TextView, к которому я хотел бы добавить подобный разметке текст.Я знаю, что это может быть достигнуто с помощью gtk.TextTag, который вы можете создать с такими же свойствами, как строка разметки Панго.Я заметил, что не существует простого способа просто сказать set_markup на gtk.TextBuffer так же, как вы можете использовать несколько других виджетов.Вместо этого вам нужно создать TextTag, присвоить ему свойства, а затем вставить его в TagTable TextBuffer's, указав теги, к которым применяется тег.

В идеале я хотел бы создать функцию, которая может преобразовывать разметку Пангострока в TextTag, чтобы получить тот же эффект.Но gtk, похоже, не имеет такой встроенной функциональности.Я заметил, что вы можете использовать pango.parse_markup() для размеченной строки, и он создаст pango.AttributeList, который содержит информацию о свойствах, установленных в строке, и индексах, в которых они встречаются.Но есть небольшие различия в каждом типе атрибута, которые затрудняют обобщение для каждого случая.Есть ли лучший способ сделать это?Или разметка панго просто не предназначена для преобразования в gtk.TextTag?

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Я наконец-то выработал собственное решение этой проблемы. Я создал функцию, которая анализирует строку разметки (используя pango.parse_markup). Благодаря чтению документации и интроспекции на python я смог понять, как взять pango.Attribute и превратить его в свойства, которые GtkTextTag может использовать.

Вот функция:

def parse_markup_string(string):
    '''
    Parses the string and returns a MarkupProps instance
    '''
    #The 'value' of an attribute...for some reason the same attribute is called several different things...
    attr_values = ('value', 'ink_rect', 'logical_rect', 'desc', 'color')

    #Get the AttributeList and text
    attr_list, text, accel = pango.parse_markup( string )
    attr_iter = attr_list.get_iterator()

    #Create the converter
    props = MarkupProps()
    props.text = text

    val = True
    while val:
            attrs = attr_iter.get_attrs()

            for attr in attrs:
                    name = attr.type
                    start = attr.start_index
                    end = attr.end_index
                    name = pango.AttrType(name).value_nick

                    value = None
                    #Figure out which 'value' attribute to use...there's only one per pango.Attribute
                    for attr_value in attr_values:
                            if hasattr( attr, attr_value ):
                                    value = getattr( attr, attr_value )
                                    break

                    #There are some irregularities...'font_desc' of the pango.Attribute
                    #should be mapped to the 'font' property of a GtkTextTag
                    if name == 'font_desc':
                            name = 'font'
                    props.add( name, value, start, end )

            val = attr_iter.next()

    return props

Эта функция создает объект MarkupProps(), который может генерировать GtkTextTag s вместе с индексом в тексте, к которому они применяются.

Вот объект:

class MarkupProps():
'''
Stores properties that contain indices and appropriate values for that property.
Includes an iterator that generates GtkTextTags with the start and end indices to 
apply them to
'''
def __init__(self): 
    '''
    properties = (  {   
                        'properties': {'foreground': 'green', 'background': 'red'}
                        'start': 0,
                        'end': 3
                    },
                    {
                        'properties': {'font': 'Lucida Sans 10'},
                        'start': 1,
                        'end':2,

                    },
                )
    '''
    self.properties = []#Sequence containing all the properties, and values, organized by like start and end indices
    self.text = ""#The raw text without any markup

def add( self, label, value, start, end ):
    '''
    Add a property to MarkupProps. If the start and end indices are already in
    a property dictionary, then add the property:value entry into
    that property, otherwise create a new one
    '''
    for prop in self.properties:
        if prop['start'] == start and prop['end'] == end:
            prop['properties'].update({label:value})
    else:
        new_prop =   {
                        'properties': {label:value},
                        'start': start,
                        'end':end,
                    }
        self.properties.append( new_prop )

def __iter__(self):
    '''
    Creates a GtkTextTag for each dict of properties
    Yields (TextTag, start, end)
    '''
    for prop in self.properties:
        tag = gtk.TextTag()
        tag.set_properties( **prop['properties'] )
        yield (tag, prop['start'], prop['end'])

Таким образом, с помощью этой функции и объекта MarkupProps я могу, учитывая строку разметки pango, разбить строку на ее свойства и текстовую форму, а затем преобразовать это в GtkTextTag s.

1 голос
/ 18 марта 2012

Не следили за развитием GTK +, возможно, они что-то добавили в последнее время, но посмотрите на эти ошибки: # 59390 и # 505478 .Поскольку они не закрыты, скорее всего, ничего не сделано.

...