Results 1 to 8 of 8

Thread: How to create a text along with curve using QPainterPath

  1. #1
    Join Date
    Jun 2012
    Posts
    3
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Unix/X11

    Default How to create a text along with curve using QPainterPath

    I am trying to build a arc with some text. I am able to create the arc and I can place the text along with curve. But so far I cant find a way ro rotate text perpendicular to the curve.
    Here is the code I am trying

    Qt Code:
    1. from __future__ import division
    2. import os
    3. import sys
    4. from PyQt4 import QtGui,QtCore
    5. import math
    6.  
    7. class PathPaintTest(QtGui.QFrame):
    8.  
    9.  
    10. def __init__(self, *args):
    11. super (PathPaintTest, self).__init__(*args)
    12. self.setMaximumSize(250, 110)
    13. self.setMinimumSize(250, 110)
    14. self.setFrameShape(QtGui.QFrame.WinPanel)
    15. self.setFrameShadow(QtGui.QFrame.Sunken)
    16.  
    17. def paintEvent(self, event):
    18. hw = QtCore.QString("Hello World")
    19. drawWidth = self.width() / 100
    20. painter = QtGui.QPainter(self)
    21. pen = painter.pen()
    22. pen.setWidth(drawWidth)
    23. pen.setColor(QtGui.QColor(QtCore.Qt.red))
    24. painter.setPen(pen)
    25. painter.translate(5,0)
    26. cc1 = QtCore.QPointF(5, -15)
    27. cc2 = QtCore.QPointF(220, -15)
    28. path1 = QtGui.QPainterPath(QtCore.QPointF(5, 140))
    29. path1.cubicTo(cc1, cc2, QtCore.QPointF(240, 140))
    30. painter.drawPath(path1)
    31.  
    32. pen.setColor(QtGui.QColor(QtCore.Qt.yellow))
    33. painter.setPen(pen)
    34. font = painter.font()
    35. font.setPixelSize(drawWidth * 5)
    36. painter.setFont(font)
    37. percentIncrease = 1 / (hw.size() + 1)
    38. perecent = 0
    39. for i in range(hw.size()):
    40. perecent+=percentIncrease
    41. point = QtCore.QPointF(path1.pointAtPercent(perecent))
    42. painter.drawText(point,QtCore.QString(hw[i]))
    43.  
    44. QtGui.QFrame.paintEvent(self,event)
    45.  
    46.  
    47. class TextTest(QtGui.QWidget):
    48. def __init__(self):
    49. super(TextTest, self).__init__()
    50. self.initUI()
    51.  
    52. def keyPressEvent(self, event):
    53. if event.key() == QtCore.Qt.Key_Escape:
    54. self.close()
    55.  
    56. def initUI(self):
    57. self.mypb = PathPaintTest()
    58. hbox = QtGui.QHBoxLayout()
    59. hbox.addWidget(self.mypb)
    60.  
    61. vbox = QtGui.QVBoxLayout()
    62. vbox.addLayout(hbox)
    63.  
    64. self.setLayout(vbox)
    65. self.setGeometry(1900, 500, 450, 180)
    66. self.setWindowTitle('Text Test')
    67.  
    68. def run():
    69.  
    70. app = QtGui.QApplication(sys.argv)
    71. ex = TextTest()
    72. ex.show()
    73. sys.exit(app.exec_())
    74.  
    75. if __name__ == "__main__":
    76. run()
    To copy to clipboard, switch view to plain text mode 
    But I am trying to achieve something close to this post http://zrusin.blogspot.com/2006/11/text-on-path.html . Like text want to be rotated based on the angle. Any idea how I can do with QPainterPath and QPainter or any other methods ?

    I am looking a output like this

    output.jpg

    Please let me know which will be the best way to achieve this .

    Thanks in advance

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,734
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to create a text along with curve using QPainterPath


  3. #3
    Join Date
    Jun 2012
    Posts
    3
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Unix/X11

    Default Re: How to create a text along with curve using QPainterPath

    I tried this code but for some reason with python I didnt get the same result . May I am missing some point.

    Here is what I am getting

    output.jpg

    This was I am looking for

    output_1.jpg

    May be I am missing something, I was looking like a out put like in my first post and here the new code I am trying


    Qt Code:
    1. from __future__ import division
    2. import os
    3. import sys
    4. from PyQt4 import QtGui,QtCore
    5. import math
    6.  
    7. class PathPaintTest(QtGui.QFrame):
    8.  
    9.  
    10. def __init__(self, *args):
    11. super (PathPaintTest, self).__init__(*args)
    12. self.setMaximumSize(250, 110)
    13. self.setMinimumSize(250, 110)
    14. self.setFrameShape(QtGui.QFrame.WinPanel)
    15. self.setFrameShadow(QtGui.QFrame.Sunken)
    16.  
    17. def paintEvent(self, event):
    18. hw = QtCore.QString("Hello World")
    19. drawWidth = self.width() / 100
    20. painter = QtGui.QPainter(self)
    21. pen = painter.pen()
    22. pen.setWidth(drawWidth)
    23. pen.setColor(QtGui.QColor(QtCore.Qt.red))
    24. painter.setPen(pen)
    25. painter.translate(5,0)
    26.  
    27. c1 = QtCore.QPointF(5, -15)
    28. c2 = QtCore.QPointF(220, -15)
    29. path = QtGui.QPainterPath(QtCore.QPointF(5, 140))
    30. path.cubicTo(c1, c2, QtCore.QPointF(240, 140))
    31. painter.drawPath(path)
    32.  
    33. pen.setColor(QtGui.QColor(QtCore.Qt.green))
    34. painter.setPen(pen)
    35. font = painter.font()
    36. font.setPixelSize(drawWidth * 10)
    37. painter.setFont(font)
    38. perecentIncrease = 1 / (hw.size() + 1)
    39. perecent = 0
    40.  
    41. for i in range(hw.size()):
    42. perecent+=perecentIncrease
    43. point = QtCore.QPointF(path.pointAtPercent(perecent))
    44. angle = path.angleAtPercent(perecent)
    45. rad = (0.017453292519943295769)*angle
    46. sina = math.sin(rad)
    47. cosa = math.cos(rad)
    48. deltaPenX = cosa * pen.width()
    49. deltaPenY = sina * pen.width()
    50. newX = (cosa * point.x()) - (sina * point.y())
    51. newY = (cosa * point.y()) + (sina * point.x())
    52. deltaX = newX - point.x()
    53. deltaY = newY - point.y()
    54. tran = QtGui.QTransform(cosa,sina,-sina,cosa,-deltaX + deltaPenX,-deltaY - deltaPenY)
    55. painter.setWorldTransform(tran)
    56. painter.drawText(point,QtCore.QString(hw[i]))
    57.  
    58. QtGui.QFrame.paintEvent(self,event)
    59.  
    60.  
    61. class TextTest(QtGui.QWidget):
    62. def __init__(self):
    63. super(TextTest, self).__init__()
    64. self.initUI()
    65.  
    66. def keyPressEvent(self, event):
    67. if event.key() == QtCore.Qt.Key_Escape:
    68. self.close()
    69.  
    70. def initUI(self):
    71. self.mypb = PathPaintTest()
    72. hbox = QtGui.QHBoxLayout()
    73. hbox.addWidget(self.mypb)
    74.  
    75. vbox = QtGui.QVBoxLayout()
    76. vbox.addLayout(hbox)
    77.  
    78. self.setLayout(vbox)
    79. self.setGeometry(300, 200, 500, 250)
    80. self.setWindowTitle('Text Test')
    81.  
    82. def run():
    83.  
    84. app = QtGui.QApplication(sys.argv)
    85. ex = TextTest()
    86. ex.show()
    87. sys.exit(app.exec_())
    88.  
    89. if __name__ == "__main__":
    90. run()
    To copy to clipboard, switch view to plain text mode 
    Last edited by achayaan; 9th June 2012 at 08:57.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,734
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to create a text along with curve using QPainterPath

    I don't have time to read your code right now, but it look like you are rotating each character by the right amount but in the wrong direction.

  5. #5
    Join Date
    Aug 2009
    Posts
    6
    Qt products
    Platforms
    Unix/X11 Windows

    Default Re: How to create a text along with curve using QPainterPath

    Thanks Chris,

    Yes I dont have any clue how I can achieve a rotation based on angle QTransform.

  6. #6
    Join Date
    Aug 2009
    Posts
    6
    Qt products
    Platforms
    Unix/X11 Windows

    Default Re: How to create a text along with curve using QPainterPath

    http://labs.qt.nokia.com/2006/11/07/text-on-a-path/ ... this looks also my solution but a google search for Zack Rusin returned https://www.facebook.com/pages/RIP-Z...830579?sk=info, if its true and if its the same Zack Rusin then its so sad

  7. #7
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,734
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to create a text along with curve using QPainterPath

    Actually, the original C++ code has the same problem. You get a better result if you make the angle negative at line 44 of your Python version.

    The solution can e simplified a little by getting Qt to do more of the mathematics:
    Qt Code:
    1. #include <QtGui>
    2. #include <cmath>
    3.  
    4. class Widget : public QWidget
    5. {
    6. public:
    7. Widget ()
    8. : QWidget() { }
    9. private:
    10. void paintEvent ( QPaintEvent *)
    11. {
    12. QString hw("hello world");
    13. int drawWidth = width() / 100;
    14. QPainter painter(this);
    15. QPen pen = painter.pen();
    16. pen.setWidth(drawWidth);
    17. pen.setColor(Qt::darkGreen);
    18. painter.setPen(pen);
    19.  
    20. QPainterPath path(QPointF(0.0, 0.0));
    21.  
    22. QPointF c1(width()*0.2,height()*0.8);
    23. QPointF c2(width()*0.8,height()*0.2);
    24.  
    25. path.cubicTo(c1,c2,QPointF(width(),height()));
    26.  
    27. //draw the bezier curve
    28. painter.drawPath(path);
    29.  
    30. //Make the painter ready to draw chars
    31. QFont font = painter.font();
    32. font.setPixelSize(drawWidth*2);
    33. painter.setFont(font);
    34. pen.setColor(Qt::red);
    35. painter.setPen(pen);
    36.  
    37. qreal percentIncrease = (qreal) 1/(hw.size()+1);
    38. qreal percent = 0;
    39.  
    40. for ( int i = 0; i < hw.size(); i++ ) {
    41. percent += percentIncrease;
    42.  
    43. QPointF point = path.pointAtPercent(percent);
    44. qreal angle = path.angleAtPercent(percent); // Clockwise is negative
    45.  
    46. painter.save();
    47. // Move the virtual origin to the point on the curve
    48. painter.translate(point);
    49. // Rotate to match the angle of the curve
    50. // Clockwise is positive so we negate the angle from above
    51. painter.rotate(-angle);
    52. // Draw a line width above the origin to move the text above the line
    53. // and let Qt do the transformations
    54. painter.drawText(QPoint(0, -pen.width()),QString(hw[i]));
    55. painter.restore();
    56. }
    57. }
    58.  
    59. };
    60.  
    61. int main(int argc, char **argv)
    62. {
    63. QApplication app(argc, argv);
    64. Widget widget;
    65. widget.show();
    66. return app.exec();
    67. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Aug 2009
    Posts
    6
    Qt products
    Platforms
    Unix/X11 Windows

    Default Re: How to create a text along with curve using QPainterPath

    thanks a lot Chris, it works perfectly ...

Similar Threads

  1. Replies: 9
    Last Post: 12th May 2014, 01:25
  2. How to create a 2d curve editor?
    By vinaym in forum Qwt
    Replies: 1
    Last Post: 4th June 2013, 06:29
  3. how to create a curve in qwtplot?
    By ethanfeng in forum Qwt
    Replies: 1
    Last Post: 27th March 2011, 09:05
  4. Replies: 5
    Last Post: 28th May 2010, 10:45
  5. How draw a rotated text in a QPainterPath?
    By iw2nhl in forum Qt Programming
    Replies: 6
    Last Post: 17th August 2007, 18:55

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.