Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Forums

OverviewFelgo 4 Support (Qt 6) › Qt6.4 : Coloring Overlapping Stars with Texture or Color from Another Object

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #25029

    Margueritte

    Hello,

    I am trying to fill an object with the texture or color of another object that overlaps it. To make it seem simpler, here is the code I have so far:

    property double note: 3.67
    
    Row {
                id: noteRow
                height: childrenRect.height
                width: childrenRect.width
                spacing: sp(10)
                anchors.horizontalCenter: parent.horizontalCenter
    
                Repeater {
                    model: 5
                    delegate: Item {
                        width: starIcon.width
                        height: starIcon.height
    
                        AppIcon {
                            id: starIcon
                            iconType: IconType.star
                        }
    
                        Rectangle {
                            id: redCover
                            width: starIcon.width
                            height: starIcon.height
                            color: "red"
                            visible: false
                        }
    
                        Component.onCompleted: {
                            let partialNote = Math.round(note * 2) / 2;
                            if (index + 1 <= Math.floor(partialNote)) {
                                redCover.visible = true;
                            } else if (index + 1 === Math.ceil(partialNote)) {
                                redCover.width = (partialNote - Math.floor(partialNote)) * starIcon.width;
                                redCover.visible = true;
                            }
                        }
                    }
                }
            }

     

    This code is used to color stars according to a rating that is assigned. However, the display shows this:

    https://ddgobkiprc33d.cloudfront.net/5be8c607-8e41-4d19-938c-93b80097f386.png

     

    While I would like to have this:

    Valid stars.png

     

    I have done several searches and came across this link: https://stackoverflow.com/questions/66604044/qml-layer-element-reveals-element-above-it-when-they-overlap
    But unfortunately, the solution provided didn’t help me.
    Searching further, I noticed that layer.effect could be a solution, so I did some research on this page: https://doc.qt.io/qt-6/qml-qtquick-shadereffect.html
    But after trying the code provided on the page, nothing is displayed:

     

    Rectangle {
        id: gradientRect;
        width: 10
        height: 10
        gradient: Gradient {
            GradientStop { position: 0; color: "white" }
            GradientStop { position: 1; color: "steelblue" }
        }
        visible: false; // should not be visible on screen.
        layer.enabled: true;
        layer.smooth: true
     }
     Text {
        id: textItem
        font.pixelSize: 48
        text: "Gradient Text"
        anchors.centerIn: parent
        layer.enabled: true
        // This item should be used as the 'mask'
        layer.samplerName: "maskSource"
        layer.effect: ShaderEffect {
            property var colorSource: gradientRect;
            fragmentShader: "mask.frag.qsb"
        }
    }

     

    So, do you have a solution to achieve coloring the stars as indicated above ?

    Thank you in advance for your answers and have a great day

    #25032

    Bence
    Felgo Team

    Hi!

    The first link you’ve looked at is actually a good solution to your problem. Maybe you’ve missed to import the Qt5 Compatible GraphicalEffects module? Here is the code where I was able to replicate your desired outcome:

    import Felgo
    import QtQuick
    import Qt5Compat.GraphicalEffects
    
    App {
    
      NavigationStack {
    
        AppPage {
          id: page
          title: qsTr("Ratings")
    
          property double note: 3.67
    
          Row {
            id: noteRow
            height: childrenRect.height
            width: childrenRect.width
            spacing: sp(10)
            anchors.centerIn: parent
    
            Repeater {
                model: 5
                delegate: Item {
                    width: starIcon.width
                    height: starIcon.height
    
                    AppIcon {
                        id: starIcon
                        iconType: IconType.star
                    }
    
                    Rectangle {
                      id: mask
                      anchors.fill: parent
                      color: "transparent"
    
                      Rectangle {
                          id: redCover
                          width: parent.width
                          height: parent.height
                          color: "red"
                      }
                      layer.enabled: true
                      layer.effect: OpacityMask {
                          maskSource: starIcon
                      }
                    }
    
                    Component.onCompleted: {
                      let partialNote = Math.round(page.note * 2) / 2;
                      if (index + 1 <= Math.floor(partialNote)) {
                          redCover.visible = true;
                      } else if (index + 1 === Math.ceil(partialNote)) {
                          redCover.width = (partialNote - Math.floor(partialNote)) * starIcon.width;
                          redCover.visible = true
                      } else { redCover.visible = false }
                    }
                }
            }
          }
        }
      }
    }

     

    Best,

    Bence

    #25033

    Margueritte

    <div class=”flex flex-grow flex-col gap-3″>
    <div class=”min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap break-words”>
    <div class=”markdown prose w-full break-words dark:prose-invert light”>

    It works! The Component.onCompleted code had an error, so I fixed it:

    Component.onCompleted: {
        let partialNote = Math.round(note * 2) / 2;
        if (index + 1 <= Math.floor(partialNote)) {
            redCover.visible = true;
        } else if (index + 1 === Math.ceil(partialNote)) {
            redCover.width = (partialNote - Math.floor(partialNote)) * starIcon.width;
            redCover.visible = true;
        } else { redCover.visible = false }
    }

     

    But now everything works perfectly.

    I had already searched with OpacityMask, but it became unavailable with Qt6. However, I understood that with import Qt5Compat.GraphicalEffects, we can import the Qt5 library, which makes the task much easier.

    Thank you! 🙂

    </div>
    </div>
    </div>

    #25034

    Margueritte

    I apologize for the double post. Upon rereading, I noticed that the difference comes from the way the note is declared in Component.onCompleted with page.note. So, my remark on this point is unnecessary ^^

Viewing 4 posts - 1 through 4 (of 4 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded