How to draw text in QQuickItem?
-
QML TextInput or QML Text Element can be used to draw text.
-
[quote author="tcmichals" date="1390932810"]Has anybody come up with a solution?[/quote]
Why didn't you try the above solution mentioned by Andre or Thomas Sander.
-
I would recommend you to use QQuickPaintedItem class that extends QQuickItem. It has method "paint", where you have QPainter as a result you can draw any text with any font/geometry. If QQuickPaintedItem is not a case for you, that you can try to draw text in "updatePaintNode" method using QSG* classes, but definitely it's much harder than with QQuickPaintedItem
-
Another method to do this would be passing a QAbstractListModel including the Text to a QML ListView so you can have as many Text Elements as you want. Create a Text as a delegate for the ListView and pass your Text to the "text" property of the Text delegate. You can modify and even set all the other properties of your Texts by accessing the childrens of your ListView which can be done from Cpp. I haven't tested it and also i don't have a code for it but it theoretically should work.
-
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);
-
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...
-
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...
-
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
-
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...
-
[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
-
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...
-
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#setTexturewith 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...