带Qml TextEdit的QTextObjectInterface(QQuickTextEdit)

时间:2014-11-11 14:50:15

标签: c++ qt qml qtextedit

我注册了简单QTextObjectInterface的处理程序,它只绘制了10x10的红色矩形。 当我在普通QWidget应用程序中使用QTextEdit时,它可以工作 当我在Qt Quick应用程序中使用QQuickTextEdit(TextEdit qml组件)时,它没有工作(没有绘制,但TextEdit中的矩形是保留的,因为当我改变光标位置时,我注意到有什么东西,但只是空的空间,没有任何东西被绘制 QTextObjectInterface intrinsicSize方法被调用(这解释了为什么我看到有空格10x10),但drawObject方法不是。

我做了一些研究,我发现问题实际上可能就在这里:

Qt 5.3.0来源(第1821行)

QQuickTextEdit.cpp

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;
}

它永远不会达到调用node->m_engine->addTextObject的程度 这是因为 if条件textFrame->firstPosition() > textFrame->lastPosition()的这一部分将评估为false 我确定了std::cout firstPostionlastPosition,当我确定了上下文时,firstPosition0lastPosition1

#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();
}

我缺少什么?

1 个答案:

答案 0 :(得分:0)

文档在

中说

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.