Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtGraphicalEffects usage questioning



  • I’ve recently started to use QtGraphicalEffects module and the effect set is really nice!
    Howerver I think the approach to apply an effect on a qml item is somewhat cumbersome.

    The "docs ":http://qt-project.org/doc/qt-5/qml-qtgraphicaleffects-coloroverlay.html give an example where we need to create an effect as a neighbour of the original item :

    @
    Item {
    width: 300
    height: 300

    Image {
        id: bug
        source: "images/butterfly.png"
        sourceSize: Qt.size(parent.width, parent.height)
        smooth: true
        visible: false
    }
    
    ColorOverlay {
        anchors.fill: bug
        source: bug
        color: "#80800000"
    }
    

    }
    @

    In this case 5 steps are needed to apply an effect:

    Create a neighbour Effect element (ColorOverlay here)

    Set orginal item as the effect source

    Set the effect size (fill original item)

    Specificy effect specific properties (color here)

    Hide the original item

    It actually feels cumbersome and not really natural for me to apply an effect this way.
    But worse than that it breaks two things : hierarchy and visibility logic.
    Indeed if you want to apply effects on existing qml code you will need to rewrite you code because this implies hierarchy changes.
    If you unfortunately use positioners or layouts elements it is a REAL PAIN since you need to create wrappers for the original item and effect otherwise you will have “holes” in your layout since those are 2 separates items.
    Lastly if you have some logic that takes care of your original item visibly, the use of effect will sadly bypass it since it renders even invisible items.

    For all those reasons I would really appreciate a better API to apply effect on on existing code without messing with hiearchy and logic.
    I then looked in the QtQuick Item API and found the “layer” attribute which seems to fill this purpose.

    So here the same effect example using the layer property :

    @
    Item {
    width: 300
    height: 300

    Image {
        id: bug
        source: "images/butterfly.png"
        sourceSize: Qt.size(parent.width, parent.height)
        smooth: true
        layer {
                enabled: true
                effect:   ColorOverlay {
           color: "#80800000"
     }
       }
    }
    

    }
    @

    Here are the needed steps with this approach:

    Set an Effect element (ColorOverlay here) as a value for the item layer property

    Enable the layering with (layer.enabled : true) => I wonder why it defaults at “false”

    Specificy effect specific properties (color here)

    I think this second approach is way more clean/simple and compatible with existing code than the first one so I’m wondering why this is not the “recommended” way to use effects in documentation.

    I’m not saying that the first approach is useless since in some cases you will need to have both the original item and the effect (e.g. mirror effect) displayed,
    But in most case for the effects in QtGraphicalEffects the effect is meant to replace the original item so the documented approach would better figured as an alternative way to do effects.

    This second approach still have some issues:

    • The type of layer property is actually “Component” not “Item” so that’s mean you can’t create alias on your effect properties
      => I 'm still wondering why the type is Component by the way
    • Even is the code doesn’t mean it, the engine seems to changes the hierarchy to render the effect => it creates a neighbour item effect under the hood
      => I created a bug report about this : https://bugreports.qt-project.org/browse/QTBUG-42949

    What do you think about this ?

    Regards,

    X-Krys



  • +1
    Nice idea, I use "many" overlay effects in my app so your second syntax would be a relief.

    I do use the first syntax mentioned in the doc so far, because as you mentioned it is impossible to access the effect with an id and maybe other "bugs" related to that?

    Also with this syntax you can only apply one effect to an item, and not 2 or more or am I missing something? The layer property should be an array and may be used like states and transitions (so you can assign a single value if you only need one). e.g.

    @
    Image {
    source: "images/butterfly.png"
    layer.effects: [
    Desaturate { desaturation: 1 },
    BrightnessContrast { brightness: -0.5 }
    ]
    }
    @
    I called the property "effects" in that example, that doesn't exists obviously :D



  • +1 for the plural form for effects ;)

    Alternatively you could nest effects

    @Image {
    source: "images/butterfly.png"
    layer.effect: Desaturate {
    desaturation: 1
    layer.effect: BrightnessContrast {
    brightness: -0.5
    }
    },
    }@

    But I also prefer the flat effect list as you suggested



  • We should vote on this bug report if we want the basic layer.effect syntax to work at first place : https://bugreports.qt-project.org/browse/QTBUG-31269


Log in to reply