Python 将pango标记字符串转换为GtkTextTag属性

Python 将pango标记字符串转换为GtkTextTag属性,python,gtk,pygtk,pango,Python,Gtk,Pygtk,Pango,我有一个gtk.TextView,我想在其中添加类似文本的标记。我知道这可以通过使用gtk.TextTag来实现,您可以使用类似于pango标记字符串的属性来创建它。我注意到,没有一种简单的方法可以像使用多个其他小部件一样,将标记设置为gtk.TextBuffer。相反,您必须创建一个TextTag,赋予它属性,然后将其插入TextBuffer的标记表中,指定标记应用于的ITER 理想情况下,我希望创建一个函数,将pango标记字符串转换为TextTag,以获得相同的效果。但gtk似乎没有内置该

我有一个
gtk.TextView
,我想在其中添加类似文本的标记。我知道这可以通过使用
gtk.TextTag
来实现,您可以使用类似于pango标记字符串的属性来创建它。我注意到,没有一种简单的方法可以像使用多个其他小部件一样,将标记设置为
gtk.TextBuffer
。相反,您必须创建一个TextTag,赋予它属性,然后将其插入TextBuffer的标记表中,指定标记应用于的ITER

理想情况下,我希望创建一个函数,将pango标记字符串转换为TextTag,以获得相同的效果。但gtk似乎没有内置该功能。
我注意到,您可以在标记的字符串上使用
pango.parse_markup()
,它将创建一个
pango.AttributeList
,其中包含有关字符串上设置的属性及其索引的信息。但每种类型的属性都有细微的差异,这使得很难对每种情况进行概括。有没有更好的办法?还是说pango标记不打算转换成gtk.TextTag?

没有关注gtk+的开发,也许他们最近添加了一些东西,但看到了这些bug:和。因为它们没有关闭,所以很可能什么也没做。

没有关注GTK+开发,也许他们最近添加了一些东西,但是看到了这些错误:和。因为它们没有关闭,所以可能什么也没做。

我终于找到了自己的解决方案。我创建了一个解析标记字符串的函数(使用
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

我终于找到了自己的解决办法。我创建了一个解析标记字符串的函数(使用
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

嗯,看来这是他们不打算支持的事情。你有没有试过解决办法?或者有什么建议吗?不是真的,我不再积极使用GTK+或PyGTK,甚至任何使用它们的项目。但是,由于这是Python,为此编写一些函数应该不会太困难(除非它不是一个方法,除非出于某种原因您已经对
gtk.TextBuffer
进行了子类化;仅为一个方法进行子类化感觉像是一种过激行为)。我同意第二个bug中概述的建议,但我当然有偏见,因为我是记者;)哦,我想我从来没有在bug报告中提到过。我将实现建议的函数和另一个创建与Pango标记相同/相似的标记的函数。因此,用法类似于
buffer.inject_pango_markup_tags();buffer.insert_解析(…)第一次呼叫只执行一次,第二次呼叫没有任何限制。谢谢您的建议。我让步了,实施了自己的解决方案。答案是postedHmm,所以他们似乎不打算支持它。你有没有试过解决办法?或者有什么建议吗?不是真的,我不再积极使用GTK+或PyGTK,甚至任何使用它们的项目。但是,由于这是Python,为此编写一些函数应该不会太困难(除非它不是一个方法,除非出于某种原因您已经对
gtk.TextBuffer
进行了子类化;仅为一个方法进行子类化感觉像是一种过激行为)。我同意第二个bug中概述的建议,但我当然有偏见,因为我是记者;)哦,我想我从来没有在bug报告中提到过。我将实现建议的函数和另一个创建与Pango标记相同/相似的标记的函数。因此,用法类似于
buffer.inject_pango_markup_tags();buffer.insert_解析(…)第一次呼叫只执行一次,第二次呼叫没有任何限制。谢谢您的建议。我让步了,实施了自己的解决方案。答案是postedIf如果有人对此代码感兴趣,我为其创建了一个存储库:如果有人对此代码感兴趣,我为其创建了一个存储库: