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 text in QQuickItem?
Forum Updated to NodeBB v4.3 + New Features

How to draw text in QQuickItem?

Scheduled Pinned Locked Moved QML and Qt Quick
24 Posts 14 Posters 17.7k Views 2 Watching
  • 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.
  • A Offline
    A Offline
    aabc
    wrote on last edited by
    #10

    I tried to use paint text with the QQuickPaintedItem paint() but sometimes it crash my application.

    Have you succeeded ?

    1 Reply Last reply
    0
    • T Offline
      T Offline
      Timmmm
      wrote on last edited by
      #11

      I used QQuickPaintedItem but unfortunately the performance was quite poor. Fortunately there was a fairly easy solution which improved performance significantly. Call this in your QQuickPaintedItem constructor:

      setRenderTarget(QQuickPaintedItem::FramebufferObject);

      1 Reply Last reply
      0
      • T Offline
        T Offline
        Timmmm
        wrote on last edited by
        #12

        Also, I've looked at the QML Text source code, and I'm afraid it is incredibly complicated to draw text the "right" QML way from C++.

        Hopefully they will provide a useful solution at some point as more people try to create custom QQuickItem's and realise they can't draw text...

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

          @Alexey: Have you found a way to render text in the QQuickItem?

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

            i also use QQuickPaintedItem, and when i am reimplement the updatePaintNode function, then i get no call for the paint function.

            Has anybody solved the problem how to render text in QQuickPaintedItem, or QQuickItem?

            I wish there is something like a public QSGTextNode...

            1 Reply Last reply
            0
            • M Offline
              M Offline
              maksim1979
              wrote on last edited by
              #15

              if you use QQuickPaintedItem, you have to reimplement
              @
              virtual void paint(QPainter *painter) override;
              @

              This paint method will be called when you invoke update(); method

              1 Reply Last reply
              0
              • A Offline
                A Offline
                aabc
                wrote on last edited by
                #16

                We don't want to use QQuickPaintedItem, We want to use QQuickItem

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Mephisto
                  wrote on last edited by
                  #17

                  Thats the point, i have reimplemented paint, but i also have reimplemented updatePaintNode...
                  Maybe i have forgotten something in my reimplementation of updatePaintNode?

                  here is some code:

                  @MyQuickPaintedItem::MyQuickPaintedItem(QQuickItem *parent)
                  : QQuickPaintedItem(parent)
                  , m_xAxisLineCount(500)
                  {
                  setFlag(ItemHasContents, true);

                  setRenderTarget(QQuickPaintedItem::FramebufferObject);
                  setPerformanceHint(QQuickPaintedItem::FastFBOResizing);
                  setAntialiasing(true);
                  //setOpaquePainting(true);
                  setMipmap(true);
                  update();
                  

                  }

                  QSGNode *MyQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
                  {
                  QSGGeometryNode *node = 0;
                  QSGGeometry *geometry = 0;

                  if (!oldNode) {
                      node = new QSGGeometryNode;
                  
                      geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_xAxisLineCount * 2);
                      geometry->setLineWidth(1);
                      geometry->setDrawingMode(GL_LINES);
                      node->setGeometry(geometry);
                      node->setFlag(QSGNode::OwnsGeometry);
                  
                      QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
                      material->setColor(QColor(255, 0, 0));
                      node->setMaterial(material);
                      node->setFlag(QSGNode::OwnsMaterial);
                  
                  } else {
                      node = static_cast<QSGGeometryNode *>(oldNode);
                      geometry = node->geometry();
                      geometry->allocate(m_xAxisLineCount * 2);
                  }
                  
                  //qDebug("in updatePaintNode");
                  
                  QRectF bounds = boundingRect();
                  QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
                  
                  
                  int iPlus = 0;
                  
                  for (int i = 0; i <m_xAxisLineCount; ++i) {
                      qreal t = i / qreal(m_xAxisLineCount - 1);
                  
                      vertices[iPlus].set(i, bounds.height() / 2.0);
                  
                      iPlus++;
                  

                  // QPointF pos_amplitude (t, 0.8 );

                  // x = bounds.x() + pos_amplitude.x() * bounds.width();
                  // y = bounds.y() + pos_amplitude.y() * bounds.height();
                  int height = bounds.height();
                  int amplitude = rand() % height;
                  //int amplitude = height;

                      vertices[iPlus].set(i, amplitude);
                      iPlus++;
                  }
                  node->markDirty(QSGNode::DirtyGeometry);
                  
                  return node;
                  

                  }

                  void MyQuickPaintedItem::paint(QPainter *painter)
                  {
                  // // Pen
                  QColor randomColor(255,255,60);
                  QPen myPenRandomColor(randomColor);

                  QRectF bounds = contentsBoundingRect();
                  
                  // Font
                  QFont font;
                  font.setFamily("Arial");
                  font.setPixelSize(20);
                  painter->setFont(font);
                  
                  painter->setPen(myPenRandomColor);
                  qDebug("in paint");
                  
                  
                  painter->drawText(bounds,Qt::AlignCenter, "text");
                  

                  }@@@@@

                  so if i take out the reimplementation of updatePaindNode, then the paint function is called...

                  some Idea how to call booth functions? i want to render text with the QPainter, but draw lines with QSG classes...

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Mephisto
                    wrote on last edited by
                    #18

                    [quote author="aabc" date="1410860899"]We don't want to use QQuickPaintedItem, We want to use QQuickItem[/quote]

                    I know, i also want to use QQuickItem, but i think if it is possible, then only with QQuickPaintedItem, if you have an idea, how to render text with QQuickItem, then is perfect, do you have?

                    greetings Tom

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      Mephisto
                      wrote on last edited by
                      #19

                      reading the qt 5.4 documentation, and maybe the "QOpenGLWidget":http://doc-snapshot.qt-project.org/qt5-5.4/qopenglwidget.html#details
                      is a good way.
                      i read, that it is possible to construct a QPainter to draw primitives and render text...

                      "this":http://blog.qt.digia.com/blog/2014/09/10/qt-weekly-19-qopenglwidget/ is also a good article about the good old QGL classes, that i use in the moment... :-( because it is new for me, and unluckily it is old and deprecated...

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Mephisto
                        wrote on last edited by
                        #20

                        I think i found a way... :-)

                        here is a blog post how to render with QPainter in an QImage or FBO...
                        "http://dangelog.wordpress.com/2013/02/10/using-fbos-instead-of-pbuffers-in-qt-5-2/":http://dangelog.wordpress.com/2013/02/10/using-fbos-instead-of-pbuffers-in-qt-5-2/

                        With this you can make a FBO and render text with QPainter in it...

                        Then you take the FBO or the QImage and create a QSGSimpleTextureNode
                        "http://qt-project.org/doc/qt-5/qsgsimpletexturenode.html#setTexture":http://qt-project.org/doc/qt-5/qsgsimpletexturenode.html#setTexture

                        with setTexture you can set the texture to it... and just append the QSGSimpleTextureNode as child to your other node, and thats it :-) i hope...

                        I will try it on monday... and report if it works...

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          literA2
                          wrote on last edited by
                          #21

                          Hi, I'm having this problem also.

                          I need to render a text on my custom geometry, I don't want to use QPainter because of the blurry text issue in iOS (using QQuickPaintedItem class).

                          Please advise. TIA.

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            seyed
                            wrote on last edited by
                            #22

                            I need it too, because performance.
                            I looked at Qt's source code (qquicktextnode.cpp) and I found following lines. Perhaps it helps someone...

                            QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
                                                             QQuickText::TextStyle style, const QColor &styleColor,
                                                             QSGNode *parentNode)
                            {
                                QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
                                QRawFont font = glyphs.rawFont();
                                bool preferNativeGlyphNode = m_useNativeRenderer;
                                if (!preferNativeGlyphNode) {
                                    QRawFontPrivate *fontPriv = QRawFontPrivate::get(font);
                                    if (fontPriv->fontEngine->hasUnreliableGlyphOutline())
                                        preferNativeGlyphNode = true;
                                    else
                                        preferNativeGlyphNode = !QFontDatabase().isSmoothlyScalable(font.familyName(), font.styleName());
                                }
                            
                                QSGGlyphNode *node = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode);
                            
                                node->setOwnerElement(m_ownerElement);
                                node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
                                node->setStyle(style);
                                node->setStyleColor(styleColor);
                                node->setColor(color);
                                node->update();
                            
                                /* We flag the geometry as static, but we never call markVertexDataDirty
                                   or markIndexDataDirty on them. This is because all text nodes are
                                   discarded when a change occurs. If we start appending/removing from
                                   existing geometry, then we also need to start marking the geometry as
                                   dirty.
                                 */
                                node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
                                node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
                            
                                if (parentNode == 0)
                                    parentNode = this;
                                parentNode->appendChildNode(node);
                            
                                return node;
                            }
                            
                            1 Reply Last reply
                            1
                            • D Offline
                              D Offline
                              devel
                              wrote on last edited by
                              #23

                              I'm making a custom QQuickItem too. And it needs to accept a delegate that'll appear in the specific position.

                              So, is it the right solution to expose a QRect property and do a QML wrapper that creates and positions that sub-item with a Loader?

                              Or it's somehow possible to attach other items directly to one of QSGNode of a custom QQuickItem?

                              1 Reply Last reply
                              0
                              • A Alexey

                                Hi,
                                I want to implement my custom QQuickItem subclass and I want it to draw some text. I found out that there is a QQuickTextNode class, but it seems to be private. So my question is: how can I do text drawing with QQuickItem?

                                Thanks in advance!

                                V Offline
                                V Offline
                                vladstelmahovsky
                                wrote on last edited by
                                #24

                                @Alexey the only way is to use QQuickText and use private classes

                                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