Search code examples
listviewqmlrectangles

Text steps out of line (window) on round rectangle. (Solution without using Qt5Compat.GraphicalEffects and OpacityMask)


I have qml ListView and inside it, I load My ListModel. My delegate component is a rectangle that holds a Text component. the Problem is when I scroll the ListView some alphabet like 'H' step out of the defined Rectangle. My defined rectangle has a round edge (radius), and the alphabet appears on the rounded edge. Is there any solution to it?

Zoomed Image

Normal View

The code sample just is a summary of the main code, imagine the list view is the whole alphabet.

blabla.qml

Rectangle{
    anchors.fill: parent
    color: "#141414"

    // Rect to keep listView component
    Rectangle {
        id: rectList
        anchors.centerIn: parent
        width: 200
        height: 400
        radius: 10
           
        ListModel{
            id: bla
            ListElement{name: "A"} ....}

        Component{
            id: delegateComponent
            Rectangle{
                id: rectListView
                width: rectList.width
                height: 30// txt.implicitHeight //removed implicitHeight
                color: "transparent"
                // radius: 10
                z: -1
                readonly property ListView __lv: ListView.view // read only property for saving model current index
                Text {
                    id: txt
                    property string __longString
                    anchors.fill: rectListView
                    anchors.left: rectListView.left
                    anchors.bottomMargin: 5
                    width: rectListView.width
                    height: rectListView.height
                    text: model.name
                   }
               }

           ListView{
               id: lv
               model: listModel
               delegate: delegateComponent
               anchors.fill: parent
               anchors.centerIn: parent
               focus: true
               clip: true
               cacheBuffer: 5000
               spacing: 15
   }

UPDATE:

Try it online


Solution

  • I cleaned up your QML:

    • I put the Rectangle into background properties, e.g. Page and Frame
    • I eliminated unnecessary sizing parameters and kept the essential ones
    • Your ListView had both anchors.fill and anchors.centerIn, it should only have one
    • I added more data to your ListModel
    • I fixed the indentation and made your snippet runnable

    Because we use Frame we give QML a hint that this object will derive it's height from the Text component that's within. The width of the Frame I use the ListView.view.width attached property.

    The Text only needs to set width: parent.width to inherit the padding width inside the Frame. I also set wordWrap: Text.WordWrap so that whilst the width is constrained, the height of the Text box will grow if the text needs to be multiline. If the Text does grow, the Frame will automatically grow with it.

    [EDIT]

    With the new requirements added, I have made the following addition changes:

    • Use padding: 0 on the Frame
    • Introduce Qt5Compat.GraphicalEffects and OpacityMask
    import QtQuick
    import QtQuick.Controls
    import Qt5Compat.GraphicalEffects
    Page {
        Rectangle {
            id: backgroundRect
            anchors.fill: parent
            color: "#89a"
        }
    
        Frame {
            id: frame
            anchors.centerIn: parent
            width: 200
            height: 400
            padding: 0
            background: Rectangle {
                radius: 10
            }
            ListView {
                id: listView
                model: SampleListModel { }
                anchors.fill: parent
                clip: true
                delegate: Frame {
                    width: ListView.view.width
                    background: Rectangle {
                        color: index & 1 ? "#eee" : "#ccc"
                    }
                    Text {
                        width: parent.width
                        text: model.name
                        wrapMode: Text.WordWrap
                    }
                }
                section.property: "group"
                section.delegate: Frame {
                    width: ListView.view.width
                    background: Rectangle {
                        color: "#60a2b3"
                    }
                    Text {
                        anchors.centerIn: parent
                        text: section
                    }
                }
            }
        }
    
        Item {
            id: backgroundMask
            anchors.fill: parent
            visible: false
            Rectangle {
                x: frame.x
                y: frame.y
                width: frame.width
                height: frame.height
                radius: 10
             }
        }
    
        OpacityMask {
            anchors.fill: parent
            source: backgroundRect
            maskSource: backgroundMask
            invert: true
        }
    }
    
    // SampleListModel.qml
    import QtQuick
    import QtQuick.Controls
    
    ListModel {
        id: listModel
        ListElement { name: "A"; group: "Group A" }
        ListElement { name: "B"; group: "Group A" }
        ListElement { name: "C"; group: "Group B" }
        ListElement { name: "D"; group: "Group B" }
        ListElement { name: "E"; group: "Group C" }
        ListElement { name: "F"; group: "Group C" }
        ListElement { name: "G"; group: "Group C" }
        ListElement { name: "H"; group: "Group C" }
        ListElement { name: "01010101001000111010100101010101110010111100011101101001010"; group: "Group D" }
        ListElement { name: "User2"; group: "Group D" }
        ListElement { name: "User3"; group: "Group D" }
        ListElement { name: "User4"; group: "Group D" }
        ListElement { name: "User5"; group: "Group D" }
        ListElement { name: "User6"; group: "Group D" }
        ListElement { name: "User7"; group: "Group D" }
        ListElement { name: "User8"; group: "Group D" }
        ListElement { name: "User9"; group: "Group D" }
        ListElement { name: "User10"; group: "Group D" }
        ListElement { name: "User11"; group: "Group D" }
        ListElement { name: "User12"; group: "Group D" }
        ListElement { name: "User13"; group: "Group D" }
        ListElement { name: "01010101001000111010100101010101110010111100011101101001010"; group: "Group D" }
        ListElement { name: "User2"; group: "Group D" }
        ListElement { name: "User3"; group: "Group D" }
        ListElement { name: "User4"; group: "Group D" }
        ListElement { name: "User5"; group: "Group D" }
        ListElement { name: "User6"; group: "Group D" }
        ListElement { name: "User7"; group: "Group D" }
        ListElement { name: "User8"; group: "Group D" }
        ListElement { name: "User9"; group: "Group D" }
        ListElement { name: "User10"; group: "Group D" }
        ListElement { name: "User11"; group: "Group D" }
        ListElement { name: "User12"; group: "Group D" }
    }
    
    

    You can Try it Online!