QTextObjectInterface with Qml TextEdit (QQuickTextEdit)

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?

+5
source share
1 answer

Documentation says in

http://doc.qt.io/qt-5/qquicktextdocument.html#details

Warning: The QTextDocument provided is used internally by Qt Quick elements to provide text manipulation primitives. You are not allowed to perform any modification of the internal state of the QTextDocument. If you do, the element in question may stop functioning or crash.

0
source

Source: https://habr.com/ru/post/1206646/


All Articles