2011-06-14 53 views
10

Tôi muốn đặt văn bản bên trong một bong bóng và tôi muốn bong bóng của tôi bằng với chiều rộng văn bản, nhưng nếu độ dài văn bản quá dài, tôi muốn văn bản tự động quấn và bằng với chiều rộng của bố mẹ.Lớp văn bản Qml (chiều rộng tối đa)

Mã này hoạt động nhưng văn bản này không gói nếu văn bản quá dài:

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

và tôi đã cố gắng này, bọc văn bản, nhưng nếu văn bản là quá nhỏ chiều rộng bong bóng không bằng văn bản kích thước:

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

Trả lời

7

Bạn có thể gần như làm điều này gọn gàng với trạng thái. Vấn đề là cố gắng để thiết lập chiều rộng của cha mẹ bằng cách gán nó cho paintWidth của hộp văn bản có nghĩa là nó sau đó thiết lập chiều rộng của hộp văn bản, mà QML phát hiện là ảnh hưởng đến paintWidth. Nó sẽ không recurse hơn nữa, nhưng QML vẫn đá ra cảnh báo. Một cách xung quanh vấn đề là làm như sau, và có một hộp văn bản vô hình giả mà chỉ cần làm việc ra cách văn bản rộng là/nên được. Đó là một chút của một hack, nhưng nó hoạt động độc đáo.

Bạn có thể thay đổi thuộc tính "khi" của trạng thái phụ thuộc vào kích thước của hộp văn bản giả (thay vì độ dài của chuỗi) nếu bạn muốn giới hạn pixel trên chiều rộng của hộp.

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

Đây là một cách khác, sử dụng tập lệnh Component.onCompleted. Đó là tĩnh hơn so với phương pháp khác của tôi, vì vậy tôi đoán nó phụ thuộc vào những gì bạn muốn làm gì với nó.

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

Tôi đã thay đổi điều này, tôi cho rằng nó tốt hơn cho perf.thx – NicoMinsk

+0

Tôi đã chơi một chút với ý tưởng kích hoạt thay đổi trên văn bản đang được sửa đổi, do đó, tạo một onTextChanged trong mục text_field, nhưng có vẻ như rằng onTextChanged được gọi trước khi paintWidth được cập nhật. Tuy nhiên, nó sẽ cho phép một cách khác để có một hộp văn bản động. Nhận xét này thực sự chỉ dành cho sự hoàn chỉnh. –

+0

Tôi thích cách tiếp cận này nhiều hơn. Tôi không cần sử dụng 'paintWidth' để so sánh,' width' cũng hoạt động. –

0

tôi không sử dụng trạng thái, nhưng tôi sử dụng ý tưởng văn bản giả để có chiều rộng. nhờ

mã của tôi:

   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

Bạn cũng có thể thử một cái gì đó như thế này, bằng cách sử dụng hộp văn bản giả đề cập ở trên:

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

này sẽ sử dụng kích thước sơn của văn bản trừ khi đó là lớn hơn chiều rộng pixel được chỉ định của bạn.

0

Hãy thử điều này:

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

Rõ ràng là một vài năm cuối, nhưng tôi chỉ chạy vào một vấn đề tương tự (mặc dù tôi đang sử dụng bõ mẫu âm chót thay vì bọc nhưng những điều cơ bản đều giống nhau). Tôi đã kết thúc với những gì có vẻ như một giải pháp đơn giản và sạch sẽ vì vậy tôi figured nếu có ai khác chạy vào vấn đề này nó có thể có thể giúp đỡ. Sử dụng mã gốc là một ví dụ:

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

Vấn đề duy nhất trong ví dụ này là với WordWrap, nếu một từ quá dài để phù hợp với toàn bộ chiều rộng của mục Text nó sẽ vượt qua bất cứ điều gì maxWidth bạn đã đặt.

Các vấn đề liên quan