2012-06-08 5 views
5

Sto provando a costruire un arco con del testo. Sono in grado di creare l'arco e posso posizionare il testo insieme alla curva. Ma finora non riesco a trovare un modo per ruotare il testo perpendicolare alla curva. Ecco il codice che sto cercandoCome creare un testo lungo una curva usando QPainterPath

from __future__ import division 
import os 
import sys 
from PyQt4 import QtGui,QtCore 
import math 

class PathPaintTest(QtGui.QFrame): 


    def __init__(self, *args): 
     super (PathPaintTest, self).__init__(*args) 
     self.setMaximumSize(250, 110) 
     self.setMinimumSize(250, 110) 
     self.setFrameShape(QtGui.QFrame.WinPanel) 
     self.setFrameShadow(QtGui.QFrame.Sunken) 

    def paintEvent(self, event): 
     hw = QtCore.QString("Hello World") 
     drawWidth = self.width()/100 
     painter = QtGui.QPainter(self) 
     pen = painter.pen() 
     pen.setWidth(drawWidth) 
     pen.setColor(QtGui.QColor(QtCore.Qt.red)) 
     painter.setPen(pen) 
     painter.translate(5,0) 
     cc1 = QtCore.QPointF(5, -15) 
     cc2 = QtCore.QPointF(220, -15) 
     path1 = QtGui.QPainterPath(QtCore.QPointF(5, 140)) 
     path1.cubicTo(cc1, cc2, QtCore.QPointF(240, 140)) 
     painter.drawPath(path1) 

     pen.setColor(QtGui.QColor(QtCore.Qt.yellow)) 
     painter.setPen(pen) 
     font = painter.font() 
     font.setPixelSize(drawWidth * 5) 
     painter.setFont(font) 
     percentIncrease = 1/(hw.size() + 1) 
     perecent = 0 
     for i in range(hw.size()): 
      perecent+=percentIncrease 
      point = QtCore.QPointF(path1.pointAtPercent(perecent)) 
      painter.drawText(point,QtCore.QString(hw[i])) 

     QtGui.QFrame.paintEvent(self,event) 


class TextTest(QtGui.QWidget): 
    def __init__(self): 
     super(TextTest, self).__init__() 
     self.initUI() 

    def keyPressEvent(self, event): 
     if event.key() == QtCore.Qt.Key_Escape: 
      self.close() 

    def initUI(self): 
     self.mypb = PathPaintTest() 
     hbox = QtGui.QHBoxLayout() 
     hbox.addWidget(self.mypb) 

     vbox = QtGui.QVBoxLayout() 
     vbox.addLayout(hbox) 

     self.setLayout(vbox) 
     self.setGeometry(1900, 500, 450, 180) 
     self.setWindowTitle('Text Test') 

def run(): 

    app = QtGui.QApplication(sys.argv) 
    ex = TextTest() 
    ex.show() 
    sys.exit(app.exec_()) 

if __name__ == "__main__": 
    run() 

Ma io sto cercando di realizzare qualcosa di simile a questo post http://zrusin.blogspot.com/2006/11/text-on-path.html. Come il testo vuole essere ruotato in base all'angolo. Qualche idea su come posso fare con QPainterPath e QPainter o altri metodi?

Cerco un output come questo

http://i.stack.imgur.com/zG9uE.jpg

Ci scusiamo per mettere il link immagine a causa della minore reputazione io sono in grado di aggiungere un'immagine al mio post.

EDIT:

Ecco alcune versione aggiornata .. la sua versione pitone di qt-project.org/faq/answer/how_do_i_make_text_follow_the_line_curve_and_angle_of_the_qpainterpath

from __future__ import division 
import os 
import sys 
from PyQt4 import QtGui,QtCore 
import math 

class PathPaintTest(QtGui.QFrame): 


    def __init__(self, *args): 
     super (PathPaintTest, self).__init__(*args) 
     self.setMaximumSize(250, 110) 
     self.setMinimumSize(250, 110) 
     self.setFrameShape(QtGui.QFrame.WinPanel) 
     self.setFrameShadow(QtGui.QFrame.Sunken) 

    def paintEvent(self, event): 
     hw = QtCore.QString("Hello World") 
     drawWidth = self.width()/100 
     painter = QtGui.QPainter(self) 
     pen = painter.pen() 
     pen.setWidth(drawWidth) 
     pen.setColor(QtGui.QColor(QtCore.Qt.red)) 
     painter.setPen(pen) 
     painter.translate(5,0) 

     c1 = QtCore.QPointF(5, -15) 
     c2 = QtCore.QPointF(220, -15) 
     path = QtGui.QPainterPath(QtCore.QPointF(5, 140)) 
     path.cubicTo(c1, c2, QtCore.QPointF(240, 140)) 
     painter.drawPath(path) 

     pen.setColor(QtGui.QColor(QtCore.Qt.green)) 
     painter.setPen(pen) 
     font = painter.font() 
     font.setPixelSize(drawWidth * 10) 
     painter.setFont(font) 
     perecentIncrease = 1/(hw.size() + 1) 
     perecent = 0 

     for i in range(hw.size()): 
      perecent+=perecentIncrease 
      point = QtCore.QPointF(path.pointAtPercent(perecent)) 
      angle = path.angleAtPercent(perecent) 
      rad = math.radians(angle) 
      sina = math.sin(rad) 
      cosa = math.cos(rad) 
      deltaPenX = cosa * pen.width() 
      deltaPenY = sina * pen.width() 
      newX = (cosa * point.x()) - (sina * point.y()) 
      newY = (cosa * point.y()) + (sina * point.x()) 
      deltaX = newX - point.x() 
      deltaY = newY - point.y() 
      tran = QtGui.QTransform(cosa,sina,-sina,cosa,-deltaX + deltaPenX,-deltaY - deltaPenY) 
      painter.setWorldTransform(tran) 
      painter.drawText(point,QtCore.QString(hw[i])) 

     QtGui.QFrame.paintEvent(self,event) 


class TextTest(QtGui.QWidget): 
    def __init__(self): 
     super(TextTest, self).__init__() 
     self.initUI() 

    def keyPressEvent(self, event): 
     if event.key() == QtCore.Qt.Key_Escape: 
      self.close() 

    def initUI(self): 
     self.mypb = PathPaintTest() 
     hbox = QtGui.QHBoxLayout() 
     hbox.addWidget(self.mypb) 

     vbox = QtGui.QVBoxLayout() 
     vbox.addLayout(hbox) 

     self.setLayout(vbox) 
     self.setGeometry(300, 200, 500, 250) 
     self.setWindowTitle('Text Test') 

def run(): 

    app = QtGui.QApplication(sys.argv) 
    ex = TextTest() 
    ex.show() 
    sys.exit(app.exec_()) 

if __name__ == "__main__": 
    run() 

ma ancora non posso riuscire ad ottenere la rotazione.

UPDATE:

ho ottenuto che funziona ora qui è la sezione aggiornata, forse aiuterà a qualcun altro anche.

painter.save() 
    painter.translate(point) 
    painter.rotate(-angle) 
    painter.drawText(QtCore.QPoint(0, -pen.width()),QtCore.QString(hw[i])) 
    painter.restore(); 
+1

si dovrebbe rispondere con la soluzione e lo accetto quindi a questa domanda non è codificata come unaswered – CoppolaEmilio

risposta

1
painter.save() 
painter.translate(point) 
painter.rotate(-angle) 
painter.drawText(QtCore.QPoint(0, -pen.width()),QtCore.QString(hw[i])) 
painter.restore(); 

Rispondendo alla mia domanda proprio a causa del commento e scusa per il ritardo di risposta :)