找到包装文本最后一行的边缘

时间:2016-08-22 20:36:22

标签: qt qml qtquick2

我有一个QML Text对象,其宽度和包裹线都是约束的:

enter image description here

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

1 个答案:

答案 0 :(得分:0)

我找到了一种疯狂的解决方案,但它对我有用。

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)
        ...
    }
}

如果您有更好的解决方案,请随时解决我的想法:)