0

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

  • Are you saying that some text looks ok, but only some of the text draws outside your rectangle? – JarMan Nov 21 '22 at 16:03
  • 1
    Note that your sample code does not define a height/width for your delegate rectangle. – JarMan Nov 21 '22 at 16:05
  • @JarMan yes exactly. The text is inside a Rectangle. If you zoom in on the image you will see it on the bottom left. – siamak mirifar Nov 21 '22 at 21:39
  • Your image is very tiny, and it's hard to understand what you expect it to look like. A more complete picture would be helpful. – JarMan Nov 21 '22 at 22:46
  • @JarMan I updated it with a new image. But the problem is the same, some pixels are out of the edge in some cases, which even on the big image you should zoom to see. – siamak mirifar Nov 22 '22 at 13:18
  • Thanks for the updated example. Are you saying you want it to clip on the rounded corner? – JarMan Nov 22 '22 at 15:26
  • 1
    Clipping is only done to rectangular regions for performance reasons. [QTBUG-9008](https://bugreports.qt.io/browse/QTBUG-9008) You could use an `OpacityMask` to achieve it [SO](https://stackoverflow.com/questions/6090740/image-rounded-corners-in-qml). – iam_peter Nov 22 '22 at 15:55
  • @JarMan yes, I dot not want the edges of the component in listView step out of the corner(Radius). It look really BAD, I found out in section.property when it is Rectangle without radius is much worth. – siamak mirifar Nov 22 '22 at 17:09
  • @iam_peter OpacityMask is for QtGraphicalEffects and it is available in Qt5 I am using Qt6 (I have to). – siamak mirifar Nov 22 '22 at 17:15
  • 1
    https://doc.qt.io/qt-6/qml-qt5compat-graphicaleffects-opacitymask.html compatibility API – iam_peter Nov 22 '22 at 17:19
  • @iam_peteruinfortunetly I can not use **QtGraphicalEffects** I do not have access to this API. – siamak mirifar Nov 23 '22 at 09:11
  • @siamakmirifar the changing requirements are not good. In future, please try to be upfront more about your requirements, and/or try splitting your questions into multiple questions, and, if your are genuinely being helped by each part, consider awarding points for each part you're being helped. Please, help provide more information giving some insight to the problem you're solving such as (1) platform, (2) version of Qt, (3) and why your library is incomplete. – Stephen Quan Nov 23 '22 at 20:47
  • @Stephen Quan, You have right, sorry it was my bad. I am not dominant on Qml and the project requirement yet. I am using the Linux Platform and Qt6. Unfortunately, I do not have Qt5 APIs and **Qt5Compat**, this is what the company has decided. They want all libraries to be native to Qt6! – siamak mirifar Nov 24 '22 at 09:20

1 Answers1

0

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!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • I have Updated a code you can check it online (Please check the post again under **Update:** is the link). In your sample code, the listview does not fill the background. There is a margin between them. – siamak mirifar Nov 22 '22 at 13:16
  • Thank you. It seems work great. I will check it tomorrow in my project. I am limited to some libraries, and I am not sure that I have **Qt5Compat.GraphicalEffects** and **OpacityMask**. – siamak mirifar Nov 22 '22 at 22:08
  • Unfortunately, I can not use OpacityMask. I do not have the API available in my sources (I am limited to some APIs). Is there any way to make it by using LayerEffects? – siamak mirifar Nov 23 '22 at 09:09