2010-09-10 26 views
1

如何使用svggraphicsItem呈现pyqt中的字形?Pyqt中的SVG字形

+1

你可以编辑这个所以这是一个问题,然后将答案部分下降到一个答案的帖子?我知道这有点强迫症,但我们喜欢这里的问答形式。谢谢。 – 2010-09-10 11:11:35

回答

3

最近我发现由开罗生成的svg文件不能在pyqt中正确绘图。错误来自使用似乎不在pyqt中显示的字形(这可能是错误的,但我找不到任何方法来获得字形渲染)。

我最终编写了一套函数将字形转换为svg路径,以便文件正常渲染。

这些仍然可以使用一些改进来渲染颜色和其他样式元素(锁定在我写的函数中)。

这些功能需要嵌入到一个类中,或者需要自行删除才能在别处使用。

我只是想让人们有这些,所以他们不必像我一样寻找一种方式来渲染pyqt中的字形。

抱最好的愿望, 凯尔

def convertSVG(self, file): 
    dom = self._getsvgdom(file) 
    print dom 
    self._switchGlyphsForPaths(dom) 
    self._commitSVG(file, dom) 
def _commitSVG(self, file, dom): 
    f = open(file, 'w') 
    dom.writexml(f) 
    f.close() 
def _getsvgdom(self, file): 
    print 'getting DOM model' 
    import xml.dom 
    import xml.dom.minidom as mini 
    f = open(file, 'r') 
    svg = f.read() 
    f.close() 
    dom = mini.parseString(svg) 
    return dom 
def _getGlyphPaths(self, dom): 
    symbols = dom.getElementsByTagName('symbol') 
    glyphPaths = {} 
    for s in symbols: 
     pathNode = [p for p in s.childNodes if 'tagName' in dir(p) and p.tagName == 'path'] 
     glyphPaths[s.getAttribute('id')] = pathNode[0].getAttribute('d') 
    return glyphPaths 
def _switchGlyphsForPaths(self, dom): 
    glyphs = self._getGlyphPaths(dom) 
    use = self._getUseTags(dom) 
    for glyph in glyphs.keys(): 
     print glyph 
     nl = self.makeNewList(glyphs[glyph].split(' ')) 
     u = self._matchUseGlyphs(use, glyph) 
     for u2 in u: 
      print u2, 'brefore' 
      self._convertUseToPath(u2, nl) 
      print u2, 'after' 

def _getUseTags(self, dom): 
    return dom.getElementsByTagName('use') 
def _matchUseGlyphs(self, use, glyph): 
    matches = [] 
    for i in use: 
     print i.getAttribute('xlink:href') 
     if i.getAttribute('xlink:href') == '#'+glyph: 
      matches.append(i) 
    print matches 
    return matches 
def _convertUseToPath(self, use, strokeD): 
    ## strokeD is a list of lists of strokes to make the glyph 
    newD = self.nltostring(self.resetStrokeD(strokeD, use.getAttribute('x'), use.getAttribute('y'))) 
    use.tagName = 'path' 
    use.removeAttribute('xlink:href') 
    use.removeAttribute('x') 
    use.removeAttribute('y') 
    use.setAttribute('style', 'fill: rgb(0%,0%,0%); stroke-width: 0.5; stroke-linecap: round; stroke-linejoin: round; stroke: rgb(0%,0%,0%); stroke-opacity: 1;stroke-miterlimit: 10; ') 
    use.setAttribute('d', newD) 
def makeNewList(self, inList): 
    i = 0 
    nt = [] 
    while i < len(inList): 
     start = i + self.listFind(inList[i:], ['M', 'L', 'C', 'Z']) 
     end = start + self.listFind(inList[start+1:], ['M', 'L', 'C', 'Z', '', ' ']) 
     nt.append(inList[start:end+1]) 
     i = end + 1 
    return nt 
def listFind(self, x, query): 
    for i in range(len(x)): 
     if x[i] in query: 
      return i 
    return len(x) 
def resetStrokeD(self, strokeD, x, y): 
    nsd = [] 
    for i in strokeD: 
     nsd.append(self.resetXY(i, x, y)) 
    return nsd 
def resetXY(self, nl, x, y): # convert a list of strokes to xy coords 
    nl2 = [] 
    for i in range(len(nl)): 
     if i == 0: 
      nl2.append(nl[i]) 
     elif i%2: # it's odd 
      nl2.append(float(nl[i]) + float(x)) 
     elif not i%2: # it's even 
      nl2.append(float(nl[i]) + float(y)) 
     else: 
      print i, nl[i], 'error' 
    return nl2 
def nltostring(self, nl): # convert a colection of nl's to a string 
    col = [] 
    for l in nl: 
     templ = [] 
     for c in l: 
      templ.append(str(c)) 
     templ = ' '.join(templ) 
     col.append(templ) 
    return ' '.join(col)