0

I wonder why this doesn't work?

ListView {
   id: root
   property var selection: QtObject {}
   ...
   delegate: MyView {
       focused: ListView.isCurrentItem
       selected: root.selection[index] === true

       Rectangle {
          id: selectionOverlay
          anchors.fill: parent
          color: "red"
          opacity: 0.3
          visible: selected
      }

   }

   Keys.onPressed: if (event.key === Qt.Key_Space) {
                        if(!root.selection[root.currentIndex])
                           root.selection[root.currentIndex] = true;
                       else 
                           root.selection[root.currentIndex] = false;
    }
}

Namely, the delegate doesn't react on the changes in the selection object. Only when delegate for the index is recreated can the selection be seen (e.g. when scrolling far enough and back).

Changing root.selection[index] to ListView.view.selection[index] doesn't help either.

I need to have selection on the ListView level to manage multi-select stuff. Have been banging my head for some time.

Thanks!

Alex Jenter
  • 4,324
  • 4
  • 36
  • 61

1 Answers1

1

The problem is that by changing a subproperty of selection propery, the changed signal for the selection property, itself won't be emitted.

QML binding mechanism only works if the value of property itself changes. But in your case, the object to which selection points never change, so you can't be notified if some subproperty of selection changes.

As a workaround you can re-assign/refresh the whole selection object, once any of its subproperties changes.

frogatto
  • 28,539
  • 11
  • 83
  • 129
  • Well I do update the current index on mouse clicks, but the problem is not with the mouse. When I press spacebar, I can see in the console that the selection property of the Listview is updated, but the delegate is not redrawn to reflect this. – Alex Jenter Dec 17 '17 at 08:38
  • Basically I need a way to tell visible delegates to check their property bindings and redraw if something has changed – Alex Jenter Dec 17 '17 at 08:40
  • @AlexJenter Bindings only work when the property value changes. In your case, it doesn't change. – frogatto Dec 17 '17 at 08:44
  • @AlexJenter I think it's better to handle selectivity at _model_ level. Can it be an option for your project? – frogatto Dec 17 '17 at 08:48
  • @AlexJenter See this question: https://stackoverflow.com/questions/19583234/qml-binding-to-an-array-element – frogatto Dec 17 '17 at 08:53
  • @AlexJenter Updated my answer. – frogatto Dec 17 '17 at 08:59
  • Why not? The visible property of selection overlay text is bound to selected property of MyView (delegate), which in it's turn is bound to the selection property of Listview, which does change. Why doesn't this binding work? Or adding a property to a QtObject is not considered to be a change? – Alex Jenter Dec 17 '17 at 09:00
  • 1
    @AlexJenter A property "change" means the address of the object which the property points to in the heap being changed. In your case adding/removing subproperties to `selection` property is not considered as a "change", since the host object (the object in the heap which `selection` points to) remains the same. – frogatto Dec 17 '17 at 09:04
  • I see. Thanks a lot for this clarification! I don't consider selection to be part of the model and wanted to leave this in QML and not pollute the model with transient fields. Would be grateful for any advice how to achieve this! – Alex Jenter Dec 17 '17 at 09:08