qtqml

How to increase height of Rectangle according to text in QML


I am not able to increase height of Rectangle (or RowLayout) wrapped around Text item that could dynamically change (chat message for example).

I tried bunch of approaches (Text.paintedHeight, childrenRect ...) but everything looks funky when text is wrapped.

My goal is display chat messages, stretch them according their wrapped text height.

Thanks for any input.

import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
visible: true

width: 900
height: 500

ColumnLayout {
    width: parent.width
    spacing: 2

    RowLayout {
        id: rowLayout
        spacing: 3

        Rectangle {
            height: 50
            width: 50
            color: "red"
        }

        Rectangle {
            id: rectangle
            width: 50
            color: "green"
            Layout.fillHeight: true
            Layout.fillWidth: true

            Text {
                id: element
                text: "If the GridLayout is resized, all items in the layout will be rearranged. It is similar to the widget-based QGridLayout. All visible children of the GridLayout element will belong to the layout. If you want a layout with just one row or one column, you can use the RowLayout or ColumnLayout. These offer a bit more convenient API, and improve readability.\n\nBy default items will be arranged according to the flow property. The default value of the flow property is GridLayout.LeftToRight.\n\nIf the columns property is specified, it will be treated as a maximum limit of how many columns the layout can have, before the auto-positioning wraps back to the beginning of the next row. The columns property is only used when flow is GridLayout.LeftToRight."
                anchors.rightMargin: 10
                anchors.leftMargin: 10
                anchors.fill: parent
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignLeft
                wrapMode: Text.WordWrap
                clip: false
                font.pixelSize: 12
            }
        }
    }
}

}


Solution

  • You have to specify the implicitHeight and implicitWidth for Rectangle (and Item for that matter).

        Rectangle {
            id: rectangle
            width: 50
            color: "green"
            Layout.fillHeight: true
            Layout.fillWidth: true
            implicitWidth: element.implicitWidth
            implicitHeight: element.implicitHeight
    
            Text {
                id: element
                anchors.fill: parent
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignLeft
                lineHeightMode: Text.FixedHeight
                wrapMode: Text.WordWrap
                clip: false
                font.pixelSize: 12
            }
        }
    

    Please note that your current setup with anchors.margins is slightly conflicting here, since that is not counted in the implicitHeight/Width, so I left them out.


    Another option would be to set the background for a Label (from QtQuick.Controls) to your desired Rectangle, that will then be stretched properly:

     Label {
          leftPadding: 10
          rightPadding: 10
          ...
          
          background: Rectangle {
              color: "green"
          }
     }
    

    In my opinion this would give you easier control about the position of your text.