2011-06-14 31 views
10

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 ajuste automáticamente y ser igual al ancho padreEnvoltura de texto Qml (ancho máximo)

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

y yo trataba de esto, el ajuste de texto, pero si el texto es demasiado pequeño el ancho de la burbuja no es igual al texto tamaño:

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

Respuesta

7

puede hacer esto casi perfectamente con los estados. El problema es que al intentar establecer el ancho del elemento principal asignándolo al ancho del cuadro de texto, significa que establece el ancho del cuadro de texto, que QML detecta como que influye en el ancho de la imagen. No recurriría más allá de esto, pero QML aún arroja advertencias. Una forma de resolver el problema es hacer lo siguiente, y tener un cuadro de texto invisible ficticio que simplemente resuelva cuán ancho es/debería ser el texto. Es un poco un truco, pero funciona muy bien.

Puede cambiar la propiedad "cuándo" del estado para que dependa del tamaño del cuadro de texto ficticio (en lugar de la longitud de la cadena) si prefiere un límite de píxeles en el ancho del cuadro.

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

Aquí hay otra forma, que utiliza el script Component.onCompleted. Es más estático que mi otro método, así 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 
     } 
    }  
} 
+0

He cambiado a esto, supongo que es mejor para perf.thx – NicoMinsk

+0

He jugado un poco con la idea de activar un cambio en el texto que se está modificando, creando así un onTextChanged dentro del elemento text_field, pero parece se llama a onTextChanged antes de que se actualice paintedWidth. Sin embargo, permitiría una forma alternativa de tener un cuadro de texto dinámico. Este comentario es realmente solo para completarlo. –

+0

Me gustó más este enfoque. No necesité usar 'paintedWidth' para comparar,' width' también. –

0

no usé el estado, pero uso la idea del 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 
        } 

      } 
2

También puede intentar algo como esto en el apartado de texto de relleno mencionada anteriormente:

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

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

0

Prueba esto:

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

Es evidente que un par de años de retraso, pero me acabo de encontrar con un problema similar (aunque estoy usando Elide en lugar de abrigo, pero los fundamentos son los mismos). Terminé con lo que parece ser una solución simple y limpia, así que pensé que si alguien más se encuentra con este problema, quizás 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 caber todo el ancho del elemento de texto que superará lo anchoMax que ha establecido.

Cuestiones relacionadas