I registred handler for simple QTextObjectInterface
, that draws just 10x10 red rectangle.
When i used QTextEdit
in normal QWidget app, it worked.
When i used QQuickTextEdit
(TextEdit qml component) in Qt Quick app, it doesn't worked (nothing is drawed, but the rectangle in TextEdit is reserved, because when i change cursor position, i notice that there is something, but just empty space, nothing is drawed.
The QTextObjectInterface
intrinsicSize
method is called (that explains why i see there is empty space 10x10), but the drawObject
method isn't.
I did some research and i found that actually the 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
is called.
It is because
this part of if
condition textFrame->firstPosition() > textFrame->lastPosition()
is evaluated to false
.
I tried std::cout
the firstPostion
and the lastPosition
when i established 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 i am missing?