2011-06-14 21 views
10

Vorrei mettere il testo all'interno di una bolla e voglio che la mia bolla sia uguale alla larghezza del testo, ma se la lunghezza del testo è troppo lunga, vorrei che il testo si avvolgesse automaticamente ed essere uguale alla larghezza genitore.Qml text wrap (larghezza massima)

Questo codice funziona, ma il testo non è avvolgente se il testo è troppo lungo:

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 ho provato questo, avvolgere il testo, ma se il testo è troppo piccola la larghezza bolla non è uguale al testo dimensioni:

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

risposta

7

È possibile quasi farlo ordinatamente con gli stati. Il problema è che il tentativo di impostare la larghezza del genitore assegnandolo a PaintWidth della casella di testo significa che quindi imposta la larghezza della casella di testo, che QML rileva come influenza PaintWidth. Non dovrebbe recedere oltre questo, ma QML continua a lanciare degli avvertimenti. Un modo per aggirare il problema è quello di fare quanto segue, e avere una finta casella di testo invisibile che si limita a capire quanto è ampio/dovrebbe essere il testo. È un po 'un trucco, ma funziona bene.

È possibile modificare la proprietà "quando" dello stato in modo che dipenda dalle dimensioni della casella di testo fittizia (anziché dalla lunghezza della stringa) se si preferisce un limite di pixel sulla larghezza della casella.

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

Ecco un altro modo, che utilizza lo script Component.onCompleted. È più statico del mio altro metodo, quindi penso che dipenda da cosa vuoi fare con esso.

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

ho cambiato, suppongo che sia meglio per perf.thx – NicoMinsk

+0

Ho giocato un po 'con l'idea di attivare una modifica sul testo in fase di modifica, quindi creare un onTextChanged all'interno dell'elemento text_field, ma sembra che onTextChanged viene chiamato prima che paintedWidth venga aggiornato. Tuttavia, consentirebbe un modo alternativo per avere una casella di testo dinamica. Questo commento è davvero solo per completezza. –

+0

Mi è piaciuto molto questo approccio. Non ho bisogno di usare 'paintedWidth' per il confronto,' width' ha funzionato pure. –

0

non ho usato stato, ma io uso l'idea di testo fittizio di avere larghezza. grazie

il mio codice:

   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

si può anche provare qualcosa di simile, utilizzando la casella di testo fittizio di cui sopra:

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

Questo userà la dimensione dipinta del testo meno che non sia maggiore della larghezza di pixel specificata.

0

Prova questo:

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

Ovviamente un paio d'anni di ritardo, ma ho appena imbattuto in un problema simile (anche se sto usando Elide invece di avvolgere ma le basi sono le stesse). Ho finito con quella che sembra una soluzione semplice e pulita, quindi ho pensato che se qualcun altro si imbatte in questo problema può forse aiutare. Utilizzando il codice originale come un esempio:

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

L'unico problema per questo esempio è che con WordWrap, se una parola è troppo lungo per essere l'intera larghezza della voce di testo supererà qualunque maxwidth è stata impostata.

Problemi correlati