Qml文字换行最大宽度

问题描述

| 我想将文本放在气泡中,并且希望气泡等于文本宽度,但是如果文本长度太长,我希望文本自动换行并等于父宽度。 此代码有效,但是如果文本太长,则文本不会自动换行:
Rectangle {
    id:messageBoxCadre
    width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width+10
    height: messageBox.height+5
    color: modelData.myMessage ? \"#aa84b2\":\"#380c47\"
    radius: 10

    Text {
        id:messageBox
        text: \'<b><font color=purple>\'+modelData.message+\'</font></b> \'
        wrapMode: \"WordWrap\"
    }
}
我尝试了这种方式,使用文本换行,但是如果文本太小,气泡宽度将不等于文本大小:
Rectangle {
    id:messageBoxCadre
    width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width+10
    height: messageBox.height+5
    color: modelData.myMessage ? \"#aa84b2\":\"#380c47\"
    radius: 10

    Text {
        id:messageBox
        width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width
        text: \'<b><font color=purple>\'+modelData.message+\'</font></b> \'
        wrapMode: \"WordWrap\"
    }
}
    

解决方法

        您几乎可以使用状态来巧妙地做到这一点。问题在于,尝试通过将父级的宽度分配给文本框的paintedWidth来设置其宽度,这意味着它随后将设置文本框的宽度,QML将其视为影响paintedWidth的对象。它不会再递归了,但是QML仍然会发出警告。解决该问题的一种方法是执行以下操作,并拥有一个虚拟的不可见文本框,该文本框可以计算出文本应该/应该有的宽度。这有点hack,但效果很好。 如果希望对框的宽度设置像素限制,则可以更改状态的“ when \”属性,使其取决于虚拟文本框的大小(而不是字符串的长度)。
import QtQuick 1.0

Rectangle {
    id: containing_rect
    property string text

    text: \"Lorem ipsum dolor sit amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat\"
    //text: \"a short string\"

    Text {
        id: text_field
        anchors.top: parent.top
        anchors.left: parent.left

        height: parent.height
        width: parent.width
        text: parent.text
        wrapMode: Text.WordWrap

    }

    Text {
        id: dummy_text
        text: parent.text
        visible: false
    }

    states: [
            State {
                name: \"wide text\"
                when: containing_rect.text.length > 20
                PropertyChanges {
                    target: containing_rect
                    width: 200
                    height: text_field.paintedHeight
                }
            },State {
                name: \"not wide text\"
                when: containing_rect.text.length <= 20
                PropertyChanges {
                    target: containing_rect
                    width: dummy_text.paintedWidth
                    height: text_field.paintedHeight
                }
            }
        ]
}
    ,        这是另一种使用Component.onCompleted脚本的方法。它比我的其他方法更静态,所以我猜它取决于您要使用它做什么。
import QtQuick 1.0

Rectangle {
    id: containing_rect
    property string text

    height: text_field.paintedHeight

    text: \"Lorem ipsum dolor sit amet,quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat\"
    //text: \"a short string\"

    Text {
        id: text_field
        anchors.top: parent.top
        anchors.left: parent.left

        height: parent.height
        width: parent.width

        text: parent.text
        wrapMode: Text.WordWrap
    }

    Component.onCompleted: {
        if (text_field.paintedWidth > 200) {
            width = 200
        } else {
            width = text_field.paintedWidth
        }
    }     
}
    ,        您也可以使用上面提到的虚拟文本框尝试类似的操作:
width: Math.min(dummy_text.paintedWidth,250)
除非它大于指定的像素宽度,否则它将使用文本的绘制大小。     ,        尝试这个:
Text {
    property int MAX_WIDTH: 400
    width: MAX_WIDTH
    onTextChanged: width = Math.min(MAX_WIDTH,paintedWidth)
}
    ,        我没有使用状态,但是我使用了虚拟文本来增加宽度。谢谢 我的代码:
                Rectangle{
                id:messageBoxCadre
                width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width+10
                height: messageBox.height+5
                color: modelData.myMessage ? \"#aa84b2\":\"#380c47\"
                radius: 10

                Text {
                    id:messageBox
                    width: (modelData.messageLength>25)? (wrapper.width - 20): dummy_text.dummy_text
                    text: \'<b><font color=purple>\'+modelData.message+\'</font></b> \'
                    wrapMode: \"WordWrap\"
                }

                Text {
                      id: dummy_text
                      text: \'<b><font color=purple>\'+modelData.message+\'</font></b> \'
                      visible: false
                  }

            }
    ,        显然晚了几年,但我遇到了一个类似的问题(尽管我使用的是elide而不是wrap,但基本知识是相同的)。我最终得到了一个看似简单,干净的解决方案,所以我认为如果有人遇到此问题可能会有所帮助。以原始代码为例:
        property int maxWidth: 100  // however you want to define the max width

        Rectangle{
            id:messageBoxCadre
            width: messageBox.paintedWidth+10  // width of the actual text,so your bubble will change to match the text width
            height: messageBox.height+5
            color: modelData.myMessage ? \"#aa84b2\":\"#380c47\"
            radius: 10

            Text {
                id:messageBox
                text: \'<b><font color=purple>\'+modelData.message+\'</font></b> \'
                width: maxWidth  // max width that your text can reach before wrapping
                wrapMode: \"WordWrap\"
            }
        }
此示例的唯一问题是使用WordWrap时,如果单词太长而无法容纳Text项的整个宽度,它将超出您设置的maxWidth。