Search code examples
qtqmlqtquick2qtquickcontrols2

Changing background and text color of a ItemDelegate


I have the material design enabled (dark theme).

Some tutorials told me to use the background property to set my own Rectangle item with custom color. Like in this screenshot:

Should later look like this

But using this technique I dont have these nice ripple effects anymore. All I wanted to do was changing the background and text color of all items.

So I tried changing propertys of background without luck. At startup the debug output told me there is no color property in background.

So I came up with a "hacky" way using Bindings... Now the properties exist!?

Is this the best way to accomplish my goal? The ripple effects appear on clicking but I dont have a good feeling with this. I dont understand why the property exist when using Bindings and why they dont exist when using normal databinding.

ItemDelegate {
    width: ListView.view.width
    height: contentItem.implicitHeight + 10

    topPadding: 5
    bottomPadding: 5

    highlighted: ListView.view.currentIndex === model.index

    //background.color: highlighted ? "#81A3CF" : "#B3B2B2"
    Binding {
        target: background
        property: "color"
        value: highlighted ? "#81A3CF" : "#B3B2B2"
    }

    text: model.index + (highlighted ? " [highlighted]" : "")

    //contentItem.color: "black"
    Binding {
        target: contentItem
        property: "color"
        value: "black"
    }

    onClicked: {
        if(ListView.view.currentIndex === model.index)
            ListView.view.currentIndex = -1;
        else
            ListView.view.currentIndex = model.index
    }
}

Solution

  • The reason is simple:

    background is declared as a Item - and Item has no color, so you can't change it, before it is assigned a concrete Item that has a color. So when you execute the QML-file, the Rectangle is not yet available, until everything is created. This is when the Binding will set the color.

    If you don't need it to be bound to anything, another solution is to use:

    Component.onCompleted: background.color = 'green'
    

    Otherwise, I deem the Binding-trick to be fine (but this is opinion!)