Вопрос:

Расположение края последней строки переносимого текста

qt qml qtquick2

392 просмотра

1 ответ

234879 Репутация автора

У меня есть Textобъект QML с ограниченной шириной и переносом строк:

введите описание изображения здесь

Text {
    width:200; height:200; wrapMode:Text.WordWrap
    text:"It's the end of the world as we know it, and I feel fine."
    Rectangle {
        width:parent.contentWidth;
        height:parent.contentHeight;
        border.color:'red'; color:'transparent'
    }
}

Я хотел бы подсчитать, где находится последний период (или только справа от него). Я пытался использовать TextMetrics, но он не поддерживает перенос (и в любом случае просто дал бы мне общую ограничивающую рамку). Я попытался использовать, onLineLaidOutчтобы прочитать ширину последней строки, но ширина всех строк равна ширине всего Textобъекта.

Как я могу найти координаты X, Y нижнего правого угла этой последней строки?


Редактировать : по запросу, вот тестовый пример, показывающий, что lineLaidOutсигнал не может быть использован для измерения widthфактически используемого:

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    id:app; visible:true; width:300; height:300
    property string message: "It's the end of the world as we know it, and I feel fine."
    Text {
        id:words; x:10; y:10
        width:150; height:150; wrapMode:Text.WordWrap
        onLineLaidOut: console.log((line.number+1)+"/"+lineCount,line.width)
        Rectangle {
            width:parent.contentWidth; height:parent.contentHeight;
            border.color:'red'; color:'transparent'
        }
    }
    Timer {
        property int chars:0
        interval:200; running:true; repeat:true
        onTriggered: words.text=message.substring(0,++chars);
    }
}

Вывод этого показывает, что line.widthэто всегда полная ширина текстового объекта, даже до того, как первая строка полностью заполнена:

qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 1/1 150
qml: 2/1 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 1/2 150
qml: 2/2 150
qml: 3/2 150
qml: 1/3 150
qml: 2/3 150
qml: 3/3 150
qml: 1/3 150
qml: 2/3 150
qml: 3/3 150
qml: 1/3 150
qml: 2/3 150
qml: 3/3 150
qml: 1/3 150
qml: 2/3 150
qml: 3/3 150
Автор: Phrogz Источник Размещён: 22.08.2016 08:36

Ответы (1)


0 плюса

3 Репутация автора

Я нашел какое-то безумное решение, но оно сработало для меня.

function findEndOfWrappedText(label) {
    var x = 0
    var y = 0
    var fakeLink = "<a href='f'>█</a>"

    var finder = function(line) {
        if (line.number !== label.lineCount - 1)
            return

        for (var i = 0; i < label.width; ++i) {
            if (label.linkAt(line.x + i, line.y + (line.height / 2))) {
                x = line.x + i
                y = line.y
                break
            }
        }
    }

    label.lineLaidOut.connect(finder)
    label.text = label.text + fakeLink
    label.lineLaidOut.disconnect(finder)
    label.text = label.text.substring(0, label.text.length - fakeLink.length)
    return Qt.point(x,y)
}

Так что все, что вам нужно сделать, это использовать эту функцию, например:

Text {
    id: label
    ...

    Component.onCompleted: {
        var point = findEndOfWrappedText(label)
        ...
    }
}

Если у вас есть лучшее решение, не стесняйтесь исправить мою идею :)

Автор: Max Bespalov Размещён: 16.03.2018 11:22
32x32