Pregunta

Me gustaría poner texto dentro de una burbuja, y quiero que mi burbuja sea igual al ancho del texto, pero si la longitud del texto es demasiado larga, me gustaría que el texto se envuelva automáticamente y sea igual al ancho principal.

Este código funciona pero el texto no está envolviendo si el texto es demasiado largo:

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

e intenté esto, envoltura de texto, pero si el texto es demasiado pequeño, el ancho de la burbuja no es igual al tamaño del texto:

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"
    }
}
¿Fue útil?

Solución

Puedes casi Haz esto cuidadosamente con los estados. El problema es que intentar establecer el ancho del padre asignándolo al ancho pintado del cuadro de texto significa que luego establece el ancho del cuadro de texto, que QML detecta como un ancho pintado influyendo. No se recurriría más allá de esto, pero QML todavía patea advertencias. Una forma de evitar el problema es hacer lo siguiente, y tener un cuadro de texto invisible ficticio que simplemente funcione cuán ancho es/debería ser el texto. Es un poco hack, pero funciona bien.

Puede cambiar la propiedad "When" del estado para depender del tamaño del cuadro de texto ficticio (en lugar de la longitud de la cadena) si prefería un límite de píxel en el ancho de la caja.

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

Otros consejos

Aquí hay otra forma, que utiliza el script componente.onCompleted. Es más estático que mi otro método, por lo que supongo que depende de lo que quieras hacer con él.

import QtQuick 1.0

Rectangle {
    id: containing_rect
    property string text

    height: text_field.paintedHeight

    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
    }

    Component.onCompleted: {
        if (text_field.paintedWidth > 200) {
            width = 200
        } else {
            width = text_field.paintedWidth
        }
    }     
}

También puede probar algo como esto, usando el cuadro de texto ficticio mencionado anteriormente:

width: Math.min(dummy_text.paintedWidth, 250)

Esto utilizará el tamaño pintado del texto a menos que sea mayor que su ancho de píxel especificado.

Prueba esto:

Text {
    property int MAX_WIDTH: 400
    width: MAX_WIDTH
    onTextChanged: width = Math.min(MAX_WIDTH, paintedWidth)
}

No usé el estado, pero uso la idea de texto ficticio para tener ancho. Gracias

mi código :

                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
                  }

            }

Obviamente, un par de años tarde, pero me encontré con un problema similar (aunque estoy usando Elide en lugar de envoltura, pero los conceptos básicos son los mismos). Terminé con lo que parece una solución simple y limpia, así que pensé que si alguien más se encuentra con este problema, tal vez pueda ayudar. Usando el código original como ejemplo:

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

El único problema para este ejemplo es que con Wordwrap, si una palabra es demasiado larga para adaptarse a todo el ancho del elemento de texto, excederá cualquier maxwidth que haya establecido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top