2011-06-14 141 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您设置的整个宽度。