I registered a handler for a simple QTextObjectInterface that draws only a 10x10 red rectangle. When I used QTextEdit in a regular QWidget application, it worked.
When I used QQuickTextEdit (TextEdit qml component) in a Qt Quick application, it did not work (nothing is drawn, but the rectangle in TextEdit is reserved because when I change the cursor position, I notice that there is something but just empty space nothing is drawn.
The QTextObjectInterface intrinsicSize method is QTextObjectInterface (this explains why I see 10x10 empty space), but the drawObject method drawObject not.
I did some research, and I found that the actual problem is probably here:
QQuickTextEdit.cpp from Qt 5.3.0 sources (line 1821)
QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) { . . . if (textFrame->firstPosition() > textFrame->lastPosition() && textFrame->frameFormat().position() != QTextFrameFormat::InFlow) { updateNodeTransform(node, d->document->documentLayout()->frameBoundingRect(textFrame).topLeft()); const int pos = textFrame->firstPosition() - 1; ProtectedLayoutAccessor *a = static_cast<ProtectedLayoutAccessor *>(d->document->documentLayout()); QTextCharFormat format = a->formatAccessor(pos); QTextBlock block = textFrame->firstCursorPosition().block(); node->m_engine->setCurrentLine(block.layout()->lineForTextPosition(pos - block.position())); node->m_engine->addTextObject(QPointF(0, 0), format, QQuickTextNodeEngine::Unselected, d->document, pos, textFrame->frameFormat().position()); nodeStart = pos; }
it never reaches the point where node->m_engine->addTextObject .
Because this part of the condition if textFrame->firstPosition() > textFrame->lastPosition() is evaluated as false .
I tried std::cout firstPostion and lastPosition when I set the context and firstPosition is 0 , lastPosition is 1 .
#include <QApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QTextDocument> #include <QQuickTextDocument> #include <iostream> #include <QTextCursor> #include <QTextBlock> #include <QPainter> #include <QAbstractTextDocumentLayout> #include <QTextCharFormat> #include "qmlcomponentspace.h" #include <QTextEdit> int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); QTextDocument * doc = engine.rootObjects().first()->findChild<QObject *>("editor")->property("textDocument").value<QQuickTextDocument *>()->textDocument(); QTextCursor cur(doc); int objectType = QTextFormat::UserObject + 1000; QmlComponentSpace * component = new QmlComponentSpace(); doc->documentLayout()->registerHandler(objectType, component); QTextCharFormat fmt; fmt.setObjectType(objectType); fmt.setForeground(Qt::red); fmt.setBackground(Qt::red); cur.movePosition(QTextCursor::End); cur.insertText(QString(QChar::ObjectReplacementCharacter), fmt); std::cout << "FIRST:" << doc->rootFrame()->firstPosition() << std::endl; std::cout << "END:" << doc->rootFrame()->lastPosition() << std::endl; return app.exec(); }
What am I missing?
source share