2011-06-14 509 views
10

我想將文本放入一個氣泡中,我希望我的氣泡等於文本寬度,但如果文本長度太長,我希望文本自動換行並等於父寬度。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" 
    } 
} 

回答

7

可以幾乎與各國爲此整齊。問題是試圖通過將其分配給文本框的paintedWidth來設置父寬度意味着它會設置文本框的寬度,QML檢測爲該寬度將影響paintedWidth。它不會比這更進一步,但QML仍然會發出警告。解決問題的一種方法是按照以下步驟進行操作,並設置一個虛擬的不可見文本框,用於確定文本的寬度和寬度。它有點破解,但效果很好。

如果您喜歡對盒子寬度的像素限制,則可以將狀態的「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 
       } 
      } 
     ] 
} 
4

下面是另一種使用Component.onCompleted腳本的方法。它比我的其他方法更靜態,所以我想這取決於你想用它做什麼。

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

我已經改變了這個,我想這對perf.thx更好 – NicoMinsk 2011-06-15 12:19:33

+0

我曾經想過觸發被修改文本的改變,所以在text_field項目中創建了一個onTextChanged,但似乎在更新paintWidth之前調用onTextChanged。但是,它將允許使用另一種方法來創建動態文本框。這個評論其實只是爲了完整。 – 2011-06-15 14:52:58

+0

我更喜歡這種方法。我不需要使用'paintedWidth'進行比較,'width'也可以。 – 2016-06-05 18:40:16

0

我沒有使用狀態,但我使用虛擬文本的想法有寬度。感謝

我的代碼:

   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

您也可以嘗試這樣的事情,使用上面提到的虛擬文本框:

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

這將使用文本的畫大小,除非它是大於指定的像素寬度。

0

試試這個:

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

顯然幾年晚,但我只是碰到了類似的問題(雖然我的Elid使用,而不是包裝,但基本是一樣的)。我最終看起來像一個簡單而乾淨的解決方案,所以我想如果有其他人遇到這個問題,它可能會幫助。使用原來的代碼爲例:

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

在這個例子中唯一的問題是,隨着自動換行,如果一個字是太長文本項目將超過任何maxWidth您設置的整個寬度。