2011-06-14 13 views
10

Chciałbym umieścić tekst wewnątrz bąbelka i chcę, aby moja bańka była równa szerokości tekstu, ale jeśli długość tekstu jest zbyt długa, chciałbym, aby tekst zawijał się automatycznie i być równe szerokości rodzica.Zawijanie tekstu Qml (maksymalna szerokość)

Ten kod działa, ale tekst nie jest zawijany, jeśli tekst jest zbyt długi:

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

i próbowałem to Oblewanie tekstem, ale jeśli tekst jest zbyt mała szerokość bańka nie jest równa tekstu rozmiar:

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

Odpowiedz

7

można prawie to zrobić porządnie ze stanów. Problem polega na tym, że próba ustawienia szerokości elementu nadrzędnego przez przypisanie jej do parametru paintedWidth w polu tekstowym oznacza, że ​​ustawia on szerokość pola tekstowego, które QML wykrywa jako wpływające na paintWidth. Nie powtórzyłoby się to dalej, ale QML wciąż generuje ostrzeżenia. Jednym ze sposobów obejścia problemu jest wykonanie poniższego i posiadanie obojętnego, niewidocznego pola tekstowego, które po prostu pokazuje, jak szeroki powinien być tekst. To trochę hack, ale działa ładnie.

Można zmienić właściwość "when" stanu, który ma być zależny od rozmiaru atrapowego pola tekstowego (a nie długości łańcucha), jeśli preferowany jest limit pikseli na szerokości ramki.

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

Oto inny sposób, który używa skryptu Component.onCompleted. Jest bardziej statyczny niż moja inna metoda, więc myślę, że to zależy od tego, co chcesz z nią zrobić.

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

Zmieniłem to, przypuszczam, że jest lepsze dla perf.thx – NicoMinsk

+0

Zrobiłem trochę z pomysłem wywołania zmiany na modyfikowanym tekście, więc tworzenie onTextChanged w obrębie elementu text_field, ale wydaje się to onTextext zmienił się przed aktualizacją paintWidth. Jednak pozwoliłoby to na alternatywny sposób posiadania dynamicznego pola tekstowego. Ten komentarz jest naprawdę tylko dla kompletności. –

+0

Podobało mi się to podejście bardziej. Do porównania nie musiałem używać 'paintedWidth', działało też' width'. –

0

Nie użyłem stanu, ale używam idei smsowego tekstu, aby mieć szerokość. Dzięki

mój kod:

   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

Możesz także spróbować coś takiego, za pomocą pola atrapę tekstu wymienionego powyżej:

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

ten użyje malowane rozmiar tekstu chyba że jest większa niż określona szerokość piksela.

0

Spróbuj tego:

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

Oczywiście kilka lat późno, ale ja po prostu wpadł na podobny temat (choć używam Elide zamiast owinąć ale podstawy są takie same). Skończyłem z czymś, co wydaje się prostym i czystym rozwiązaniem, więc pomyślałem, że jeśli ktoś inny wpadnie na ten problem, może może pomóc. Korzystanie z oryginalnego kodu jako przykład:

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

Jedyny problem w tym przykładzie jest to, że z WordWrap, jeśli słowo jest zbyt długa, by zmieścić całą szerokość elementu tekst będzie dłuższy niż cokolwiek maxwidth zostały ustawione.