0

So I have been trying for weeks to simply get my text to wrap when it gets to to end of the rectangle. I have tried loads of things and this snippet is just the latest. Even if I use Layout ONLY and drop the "anchor" it does not do word wrapping, instead the text looks like the width is not set. Even if I force the rectangle and text width it just gets ignored.

var elem = '
    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.15

    RowLayout {
        id: rowlayout
        //anchors.fill: parent
        Layout.minimumHeight: 100
        Layout.preferredHeight: 100
        Layout.maximumHeight: 100
        spacing: 6
        Rectangle {
            id: element_one_rect
            color: "'+active+'"
            Layout.fillWidth: true
            Layout.minimumWidth: root.width * 0.25
            Layout.preferredWidth: root.width * 0.25
            Layout.maximumWidth: root.width * 0.25
            Layout.minimumHeight: 100
            Layout.margins: 10
            Text {
                anchors.centerIn: parent
                text: "'+description+'"
                color: "'+color+'"
                font.weight: Font.DemiBold
            }
        }
        Rectangle {
            color: "'+active+'"
            Layout.fillWidth: true
            Layout.minimumWidth: root.width * 0.72
            Layout.preferredWidth: root.width * 0.72
            Layout.preferredHeight: 100
            Layout.margins: 10
            Text {
                anchors.centerIn: parent
                text: "'+data+'"
                color: "'+color+'"
                font.weight: Font.Bold
                //wrapMode: Text.WordWrap
                wrapMode: Text.WrapAnywhere
            }
        }
    }';

2 Answers2

1

I would not expect the Text element to wrap without knowing its fixed size. So adding something like width: parent.width to your text element should make it wrap.

Luca Carlon
  • 9,546
  • 13
  • 59
  • 91
0

The problem as @LucaCarlon also indicated is that width has not been set. To demonstrate, look at the following minimal test:

    Rectangle {
        width: 250
        height: 250
        color: "grey"
        Text {
            text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
            //width: 100
            //width: 200
            //width: 300
            //width: parent.width
            //wrapMode: Text.Wrap
            //wrapMode: Text.WordWrap
            //wrapMode: Text.WrapAnywhere
        }
    }

If you enable any of the wrapMode above but do not provide a width, you will observe the wrapMode is ignored. This makes sense because whilst it is willing to wrap, it doesn't know what to wrap to. Then, when you enable any of the width choices, you will suddenly observe that the word wrap will start working for you. Based on how your example reads, it seems that you are needing width: parent.width. This was also the conclusion that @LucaCarlon came to quite early on.

You can Try a demo online.

I also did a review of your code and came up with additional recommendations:

  1. Your code appears to be from a snippet that does code injection
    • I highly recommend against that, because it introduces security and performance problems
  2. Avoid using complex formula for Layout widths and heights
    • It's better to allow it to size things for you
    • If you use Layout.fillWidth with Layout.preferredWidth the RowLayout will allocate ratioed spacing for your components
  3. As per @GrecKo's suggestion of using Label instead of Text so you can use background and padding to stylize a frame and avoid unnecessary pixel calculations
  4. Also as per @GrecKo's suggestion use Text.Wrap which achieves a balance between Text.WordWrap and Text.WrapAnywhere

Here's a demonstration of the above:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Page {
    property string txt: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
    property color activeColor: "green"
    property color textColor: "white"
    RowLayout {
        id: rowlayout
        width: parent.width
        anchors.verticalCenter: parent.verticalCenter
        Label {
            Layout.fillWidth: true
            Layout.preferredWidth: 200
            background: Rectangle { color: activeColor }
            padding: 10
            text: txt
            color: textColor
            font.weight: Font.DemiBold
            wrapMode: Text.Wrap
        }
        Label {
            Layout.fillWidth: true
            Layout.preferredWidth: 400
            background: Rectangle { color: activeColor }
            padding: 10
            width: parent.width
            text: txt
            color: textColor
            font.weight: Font.Bold
            //wrapMode: Text.WordWrap
            //wrapMode: Text.WrapAnywhere
            wrapMode: Text.Wrap
        }
    }
}

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • Your original answer consisted of two points: one was from my answer, which preceded yours of hours, the second was simply wrong and I had already provided the Qt code to show it. Now you removed the errors, but the critical point remains the one I provided. A downvote seems reasonable to me, sorry. – Luca Carlon Mar 26 '23 at 11:34
  • @LucaCarlon you also edited your answer. In your original answer, you expressed you had not tried it. Because of that comment, I actually hadn't read the details of your answer. I investigated my own answer. Whilst it may appear to be a derivated of yours, it was not. I went about it on my own and by coincidence realize it overlapped yours afterward. When I realized it, I took measures to credit you. – Stephen Quan Mar 26 '23 at 12:21
  • @LucaCarlon about my error. I wanted to express a recommendation for Text.WrapAtWordBoundaryOrAnywhere over the Text.WrapAnywhere enumerated type. The argument I made was poor, and, hence, opened myself to blunder. However, the intent remains in that I still recommend that enumerated type. My overall intent is to provide a holistic response and I did hope to provide broad constructive feedback even though it may not have been solicited. – Stephen Quan Mar 26 '23 at 12:24
  • 1
    for 3: no need for a `Frame` if you are using `Label`, it already has a `background` and a `padding` property. If you really want to use a container control, `Pane` is less specific than `Frame` for 4: `Text.WrapAtWordBoundaryOrAnywhere` is not documented anymore and was always equivalent to `Text.Wrap`, just use that. – GrecKo Mar 27 '23 at 09:30
  • @GrecKo thanks. I made an edit based on all of your suggestions. – Stephen Quan Mar 27 '23 at 09:47