How to decompose ListElement property on multiple rows
P粉083785014
P粉083785014 2024-02-21 18:56:23
0
2
439

I'm trying to figure out how to do a multi-row ListElement property.

I have a ListModel with ListElements like this:

ListElement {
   key: "key";
   value: 1;
   description: "Very long, full paragraph description that extends way off the screen which I would like to wrap in code nicely."
}

I can wrap lines by simply entering a newline character, but subsequent lines will not align with the text block.

   description: "Very long, full paragraph description
that extends way off the screen which I would like to
wrap in code nicely."

When I try to tab on the text to align it, it results in a lot of whitespace when the description prints to the screen (which makes sense, but is obviously not what I want).

   description: "Very long, full paragraph description
               that extends way off the screen which I would like to
               wrap nicely in code."
Very long, full paragraph description             that extends way off the screen which I would like to
            wrap in code nicely.

I tried connecting via " ", but this produced the error: ListElement: Unable to get property value using script.

I've tried using backslashes like in the .pro file, but that doesn't work either.

Line breaks work, but they don't matter because they don't solve the whitespace problem.

Very long, full paragraph description
            that extends way off the screen which I would like to
            wrap in code nicely.

If anyone has any ideas I would be grateful.

P粉083785014
P粉083785014

reply all(2)
P粉020556231

First, you may consider using Javascript backtick notation to declare multi-line strings.

ListElement {
            key: "key"
            value: 1
            description: `Very long, full paragraph description
that extends way off the screen which I would like to
wrap in code nicely.`
        }

In addition to this, you may find that the ListElement declaration is restrictive and does not support Javascript expressions such as Date.now(). In these cases, you can Consider using imperative code. If you want a somewhat declarative look, you can declare an array of Javascript objects and iterate over it.

When rendering, you may also consider using wrapMode: Text.Wrap to apply additional word wrapping to format the text.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    ListModel {
        id: listModel
        ListElement {
            key: "key"
            value: 1
            time: 01683504000000
            description: `Very long, full paragraph description
that extends way off the screen which I would like to
wrap in code nicely.`
        }
        property var initData: [{
            key: "key2",
            value: 2,
            time: Date.now(),
            description: `Very long, full paragraph description
that extends way off the screen which I would like to
wrap in code nicely.`.replace(/\n/g, " ")
         },{
            key: "key3",
            value: 3,
            time: (new Date("2023-05-09").getTime()),
            description: `Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec odio. Quisque volutpat mattis eros.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec odio. Quisque volutpat mattis eros.`
         },{
            key: "key4",
            value: 4,
            time: (new Date("2023-05-10").getTime()),
            description: `Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec odio. Quisque volutpat mattis eros.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec odio. Quisque volutpat mattis eros.`.replace(/\n/g, " ")
         },{
            key: "key5",
            value: 5,
            time: (new Date("2023-05-11").getTime()),
            description: [
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
"Donec odio. Quisque volutpat mattis eros.",
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
"Donec odio. Quisque volutpat mattis eros.",
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
"Donec odio. Quisque volutpat mattis eros."
].join(" ")
         }]
         Component.onCompleted: {
             for (let obj of initData) {
                 append(obj);
             }
         }
    }
    ListView {
        anchors.fill: parent
        model: listModel
        ScrollBar.vertical: ScrollBar {
            width: 20
            policy: ScrollBar.AlwaysOn
        }
        delegate: Frame {
            width: ListView.view.width - 20
            background: Rectangle {
                color: index & 1 ? "#eee" : "#ddd"
                border.color: "#ccc"
            }
            ColumnLayout {
                width: parent.width
                Text { text: `key: ${key}` }
                Text { text: `time: ${new Date(time)} (${time})` }
                Text { text: `value: ${value}` }
                Text {
                    Layout.fillWidth: true
                    text: description
                    wrapMode: Text.Wrap
                }
            }
        }
    }
}

You cantry it online!

P粉242126786

I don't have a direct solution for the implementation you are using that creates ListElements directly. But ListModel's .append() method does take a JS object as a parameter. These support multi-line strings. So instead of creating ListElements like this, you can append them when the component is complete like this:

ListModel {
    id:listModel

    Component.onCompleted: {
        listModel.append({
            "key": "key",
            "value": 1,
            "description": "Very long, full paragraph description" +
            "that extends way off the screen which" +
            "I would like to wrap in code nicely."
        })
    }
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template