Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to draw Bezier curves in QML?
QtWS25 Last Chance

How to draw Bezier curves in QML?

Scheduled Pinned Locked Moved QML and Qt Quick
16 Posts 8 Posters 17.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    moo1
    wrote on last edited by
    #3

    Can you just use SVG as a source for the Image element? You shouldn't need any extension.

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Fenix Voltres
      wrote on last edited by
      #4

      [quote author="moo1" date="1301956183"]Can you just use SVG as a source for the Image element? You shouldn't need any extension.[/quote]

      I can't, because I need these lines to dynamically adjust their shapes while I'm moving boxes. :/

      When temptation brings me to my knees
      And I lay here drained of strength
      Show me kindness
      Show me beauty
      Show me truth

      1 Reply Last reply
      0
      • frankcyblogic.deF Offline
        frankcyblogic.deF Offline
        frankcyblogic.de
        wrote on last edited by
        #5

        Hmmm... in theory even a border image would do. Compute start and end point, derive angle, rotate the arrow image, etc. Of course the arrow head needs to be fully inside the border.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Merinas
          wrote on last edited by
          #6

          I've made an extension for myself, which allow me to draw line, with cubic option.
          You will need to create a qml plugin. And to something like that
          :
          @void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
          {

          //setting drawing param
          painter->setRenderHint(QPainter::Antialiasing);
          painter->setPen(Qt::NoPen);

          // Construct the main path
          QPainterPath totalPath;
          totalPath.moveTo(m_points.at(0)->x(),m_points.at(0)->y());
          for (int i=1; i<m_points.size(); ++i)
          {
          totalPath.lineTo(m_points.at(i)->x(),m_points.at(i)->y());
          }

          //drawing directly
          painter->strokePath(totalPath, QPen(m_pencolor, m_penWidth));

          }@

          For adding cubic you could look at the "path stroking exampe":http://doc.qt.nokia.com/latest/demos-pathstroke.html

          And no you could not use an svg file because the svg is just render once at start.

          1 Reply Last reply
          0
          • F Offline
            F Offline
            Fenix Voltres
            wrote on last edited by
            #7

            Merinas,
            I've made similar thing as you and it works literally halfway - when I move one anchor point only the left and upper areas are updated.
            Doeas anyone have an idea how to fix it?

            Here is how it looks like:

            http://student.agh.edu.pl/~wmaciej/nodes.png

            my paint() fction:

            @void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
            {
            QPainterPath path;

            painter->setRenderHint(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);
            
            QPointF middle1( (m_startingPoint.x() + m_endingPoint.x())/4, (m_startingPoint.y() + m_endingPoint.y())/2 );
            QPointF middle2( 3*(m_startingPoint.x() + m_endingPoint.x())/4, (m_startingPoint.y() + m_endingPoint.y())/2 );
            
            path.moveTo(m_startingPoint.x(), m_startingPoint.y());
            path.cubicTo( middle1.x(), middle1.y(),
                          middle2.x(), middle2.y(),
                          m_endingPoint.x(), m_endingPoint.y() );
            
            painter->strokePath( path, QPen(m_penColor, m_penWidth) );
            

            // painter->setPen( QPen(Qt::red) );
            // painter->drawRect( path.boundingRect().normalized() );
            }@

            Whole code can be found "here":http://student.agh.edu.pl/~wmaciej/LineTest.zip.

            When temptation brings me to my knees
            And I lay here drained of strength
            Show me kindness
            Show me beauty
            Show me truth

            1 Reply Last reply
            0
            • M Offline
              M Offline
              Merinas
              wrote on last edited by
              #8

              Your right image is really strange... Oo Cubic was working fine for me since have use Qt example code so I can't really help you. Maybe you can build a gif showing your issue. This may help us to understand what goes wrong...

              1 Reply Last reply
              0
              • F Offline
                F Offline
                Fenix Voltres
                wrote on last edited by
                #9

                After some experiments I think it's general QML-related problem, not generated by my implementation.
                But it's behavior is very strange:

                If I connect starting and ending points of my curve to some points on two QML Rectangles it looks fine.
                When I move the rectangles (with MouseArea's drag) Qt updates only the region from (window's) 0,0 to lower right point of moving rectangle, no matter where my line is pinned to. It means in the case the whole curve is placed above moving rect's lower right corner, everything updates as it should; otherwise (= when whole curve's bounding rect is not contained in mentioned area) only that part which's in is updated.

                What's more, when my curve is displayed wrongly and the window needs to be repainted - i.e. I change it's size or click on other window to lose focus - curve * magically * updates correctly.

                Explixitly calling QDeclarativeView object to update itself doesn't help.

                Does anyone have the idea what can I do? It's really important for me to have cubic lines available from QML..

                @_Merinas_:
                Yeah, it's a bit hard to explain what my particular problem is, so besides my story here is a gif:

                !http://student.agh.edu.pl/~wmaciej/QML-line.gif(my problem)!

                Hope it's gonna help you understand what I mean.

                When temptation brings me to my knees
                And I lay here drained of strength
                Show me kindness
                Show me beauty
                Show me truth

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  rselva123
                  wrote on last edited by
                  #10

                  The line breaks in windows but I don't see any problem in Qt simulator. Works as expected - no broken line. So it's some bug in QML specific to windows.

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    Fenix Voltres
                    wrote on last edited by
                    #11

                    In the beggining I thought you're talking about the OS, so I switched to Linux - but this error is also present there.

                    I found a brute-force workaround: automatically resize top window by 1px back and forth.
                    Pitiful and very CPU-eating, but works for now.

                    Shold I report this as a bug?

                    When temptation brings me to my knees
                    And I lay here drained of strength
                    Show me kindness
                    Show me beauty
                    Show me truth

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #12

                      Yes, please report, but please add your (minimal) testcase to your bugreport and also link back and forth between this topic and the bug report.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Merinas
                        wrote on last edited by
                        #13

                        When the point of the curve move, Haven't you forget to call the update function ?

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mbrasser
                          wrote on last edited by
                          #14

                          Hi,

                          Does setting QGraphicsView::FullViewportUpdate on the QDeclarativeView work?

                          Does your Line element set a width and height? This is needed by QDeclarativeItem's "boundingRect":http://doc.qt.nokia.com/4.7/qgraphicsitem.html#boundingRect implementation (which determines what area needs to be repainted when update() is called for the element).

                          Regards,
                          Michael

                          1 Reply Last reply
                          0
                          • F Offline
                            F Offline
                            Fenix Voltres
                            wrote on last edited by
                            #15

                            [quote author="Merinas" date="1302507353"]When the point of the curve move, Haven't you forget to call the update function ? [/quote]

                            No, I haven't forgot;

                            [quote author="mbrasser" date="1302567263"]Hi,

                            Does setting QGraphicsView::FullViewportUpdate on the QDeclarativeView work?

                            Does your Line element set a width and height? This is needed by QDeclarativeItem's "boundingRect":http://doc.qt.nokia.com/4.7/qgraphicsitem.html#boundingRect implementation (which determines what area needs to be repainted when update() is called for the element).

                            Regards,
                            Michael[/quote]

                            Setting QGraphicsView::FullViewportUpdate on QDeclarativeView works fine - it's still CPU-eating, but it better solution than mine previous;
                            I didn't implement boundingRect() method at all, nor I set width and height. After doing this it's a bit better - the rectangle in which my line is updated is bigger than previously, but it differs - sometimes whole line is updated, sometimes not.

                            Is there any particular order I should set new values in in paint() method? Now it looks like this:
                            @
                            void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
                            {
                            painter->setRenderHint(QPainter::Antialiasing);
                            painter->setPen(Qt::NoPen);

                            QPointF middle1( (m_startingPoint.x() + m_endingPoint.x())/10, m_startingPoint.y() );
                            QPointF middle2( 9*(m_startingPoint.x() + m_endingPoint.x())/10, m_endingPoint.y() );
                            
                            QPainterPath path;
                            path.moveTo( m_startingPoint );
                            path.cubicTo( middle1, middle2, m_endingPoint );
                            
                            rect = path.boundingRect();
                            setHeight( rect.height() );
                            setWidth( rect.width() );
                            
                            painter->strokePath( path, QPen(m_penColor, m_penWidth) );
                            

                            // painter->setPen( QPen(Qt::red) );
                            // painter->drawRect( boundingRect() );
                            }

                            QRectF Line::boundingRect()
                            { return rect; }
                            @

                            Anyway - thank you, mbrasser, it's one step closer. :)

                            [EDIT:]

                            Testing goes on:

                            • Calling prepareGeometryChange(); inside a paint() method wasn't best idea. ;)

                            • As I see the problem is in these lines:

                            @ setHeight( rect.height() );
                            setWidth( rect.width() );@

                            When I set width and height properly bigger, it works. Just don't know the correct equation for these values to work in every case.

                            When temptation brings me to my knees
                            And I lay here drained of strength
                            Show me kindness
                            Show me beauty
                            Show me truth

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              Jason.He
                              wrote on last edited by
                              #16

                              @i think that is very easy to do .like below...just a simplest example!

                              import QtQuick 1.0

                              Rectangle {
                              id: rect;
                              width: 450;
                              height:800;
                              PathView {
                              id: pathView;
                              model: 300;
                              delegate: Rectangle {
                              id: dot;
                              width: 1; height: 1;
                              color: "black";
                              }
                              path: Path {
                              startX: 20; startY: 0
                              PathCubic {
                              x: 180; y: 0
                              control1X: -10; control1Y: 90
                              control2X: 210; control2Y: 90
                              }
                              }
                              }
                              }

                              another version! perfect result!

                              import QtQuick 1.0

                              Rectangle {
                              id: rect;
                              width: 450;
                              height:800;
                              PathView {
                              id: conrPaV;
                              anchors.fill: parent;
                              model: 900;
                              delegate: Rectangle {
                              id: dot;
                              width: 1; height: 1;
                              color: "red";
                              }

                                  path: Path {
                                      id: ph;
                                      startX: 0.0; startY: conrPaV.height/2.0;
                                      PathQuad {
                                          x: 40.0; y: conrPaV.height/2.0;
                                          controlX: 20.0; controlY: ph.startY -60.0;
                                      }
                                      PathQuad {
                                          x: 80.0; y: conrPaV.height/2.0;
                                          controlX: 60.0; controlY: ph.startY +60.0;
                                      }
                                  }
                              }
                              

                              }

                              @

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved