silvansky programming stuff

16Nov/100

qml & multiline elide

иногда нужно обрезать длинную строку и поставить в конце многоточие... для этого в QML у текста есть свойство elide. чтобы его задействовать нужно задать ширину текста.

а что если мы хотим вывести текст в 2 строки? и при этом естественно обрезать лишнее и поставить многоточие?...
тогда elide бессилен.

немного результатов моих мучений с данным вопросом: рабочая функция многострочного илайда!

сразу перейдём к коду.

Text {
    id: tempText
    visible: false
    width: parent.width
    wrapMode: Text.WordWrap
    function elideMultiline(text, font, linesCount) {
        tempText.font = font
        var l = text.length
        var s = "";
        for (var i = 0; i < linesCount; i++) {
            s += "W";
            if (i < linesCount - 1)
                s += "\n"
        }
        tempText.text = s
        var maxHeight = tempText.paintedHeight
        tempText.text = text
        while (tempText.paintedHeight > maxHeight) {
            tempText.text = text.substring(0, --l) + "..."
        }
        return tempText.text
    }
}
Text {
    id: longText
    width: parent.width
    wrapMode: Text.WordWrap
    font.pointSize: 16
    Component.onCompleted: {
        text = tempText.elideMultiline("my very-very-very-very and very long text with a lot of words in it and which i want to be correctly elided", font, 2)
    }
}

как видно из кода, создаётся дополнительный элемент Text и делается невидимым. он используется для определения размеров текста на экране. для этого элемента определяем функцию elideMultiline, в неё передаём текст, шрифт и нужное нам количество строк текста.

далее всё просто, простой линейный перебор (сокращаем строку на 1 символ, дописываем "...", проверяем, опять сокращаем.......)

в принципе всё работает, но когда нужно вызвать эту функцию много раз, получаются тормоза. как дойдут руки, переделаю из линейного поиска в метод золотого сечения.

Замечание. Почему-то не хочет работать text: elideMultiline(), поэтому используется событие готовности компонента и в нём делается присвоение. Если сделать всё же первый вариант, то всё будет тормозить и выдавать кучу предупреждений "QML Text: Binding loop detected for property "text""

Tagged as: , , , , No Comments