【问题标题】:Qml text wrap (max width)Qml 文本换行(最大宽度)
【发布时间】:2011-09-14 18:25:44
【问题描述】:

我想将文本放在气泡中,我希望我的气泡等于文本宽度,但是如果文本长度太长,我希望文本自动换行并等于父宽度.

此代码有效,但如果文本太长,则文本不会换行:

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

【问题讨论】:

    标签: qt qml qt-quick


    【解决方案1】:

    聚会很晚,但干净的解决方案是使用嵌入式TextMetrics 对象。像这样:

    ...
    Text {
      id: textObj
      width: Math.min(textWidth, myThreshold)
    
      // access to binding-loop-free width and height:
      readonly property alias textWidth: textMetrics.boundingRect.width
      readonly property alias textHeight: textMetrics.boundingRect.height
    
      TextMetrics {
        id: textMetrics
        font: textObj.font
        text: textObj.text
        elide: textObj.elide
      }
    }
    

    【讨论】:

      【解决方案2】:

      显然晚了几年,但我刚刚遇到了类似的问题(虽然我使用的是 elide 而不是 wrap,但基本原理是相同的)。我最终得到了一个看似简单而干净的解决方案,所以我想如果其他人遇到这个问题,它可能会有所帮助。以原代码为例:

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

      此示例的唯一问题是,使用 WordWrap,如果一个单词太长而无法容纳 Text 项的整个宽度,它将超过您设置的任何 maxWidth。

      【讨论】:

        【解决方案3】:

        试试这个:

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

        【讨论】:

          【解决方案4】:

          您也可以使用上面提到的虚拟文本框尝试这样的操作:

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

          这将使用文本的绘制大小,除非它大于您指定的像素宽度。

          【讨论】:

            【解决方案5】:

            我没有使用状态,但我使用虚拟文本的想法来拥有宽度。谢谢

            我的代码:

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

            【讨论】:

              【解决方案6】:

              这是另一种方式,它使用 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
                      }
                  }     
              }
              

              【讨论】:

              • 我玩了一点触发更改正在修改的文本的想法,因此在 text_field 项中创建了一个 onTextChanged,但似乎在更新paintWidth 之前调用了 onTextChanged。但是,它将允许使用另一种方法来拥有动态文本框。此评论实际上只是为了完整性。
              • 我更喜欢这种方法。我不需要使用paintedWidth 进行比较,width 也可以。
              【解决方案7】:

              你可以几乎用状态巧妙地做到这一点。问题是尝试通过将父级分配给文本框的paintWidth 来设置父级的宽度意味着它会设置文本框的宽度,QML 将其检测为影响paintWidth。它不会比这更进一步,但 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
                              }
                          }
                      ]
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-03-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-06-23
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多