web-dev-qa-db-ja.com

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

あなたはほぼこれを州できちんと行うことができます。問題は、親の幅をテキストボックスのpaintedWidthに割り当てて設定しようとすると、テキストボックスの幅が設定され、QMLがpaintedWidthに影響を与えると検出することです。これ以上再発することはありませんが、QMLは警告を発します。この問題を回避する1つの方法は、次のようにして、テキストの幅/幅を計算するダミーの非表示のテキストボックスを用意することです。ちょっとしたハックですが、うまく機能します。

ボックスの幅にピクセル制限を設定したい場合は、状態の「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
                }
            }
        ]
}
8
Henry Gomersall

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
        }
    }     
}
5
Henry Gomersall

上記のダミーテキストボックスを使用して、次のようなことを試すこともできます。

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

これは、指定されたピクセル幅より大きくない限り、テキストのペイントされたサイズを使用します。

2
Thane Brimhall

これを試して:

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

明らかに数年遅れましたが、私はちょうど同様の問題に遭遇しました(私はラップの代わりにエリジオンを使用していますが、基本は同じです)。シンプルでクリーンな解決策のように思えたので、他の誰かがこの問題に遭遇した場合、それが役立つかもしれないと考えました。例として元のコードを使用する:

        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を使用すると、Wordが長すぎてテキスト項目の幅全体に収まらない場合、設定したmaxWidthを超えることです。

0
Sebastian

状態は使用しませんでしたが、幅を持たせるためにダミーテキストのアイデアを使用しています。ありがとう

私のコード:

                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
                  }

            }
0
NicoMinsk