Mark
Mark

Reputation: 5132

QML: StackView and C++ bound variables

With Qt5.7, I use a StackView to switch among several QML Objects:

StackView {
    id: stack
    anchors.fill: parent
    initialItem: initObj
}

Component {
    id: initObj
    ModuleHome {}
}

Component {
    id: obj1
    Module1 {}
}

// ...

stack.push({item: item, replace: true, destroyOnPop: true})

where item is i.e. obj1. It works and I can easily add an animation for the transitions.

The problem is inside my objects. Some of them have some variables bound to C++, that I use to update the UI, i.e.:

property int itemSize: MyClass.itemSize
onItemSizeChanged {
    // do something
}

Before migrate to StackView all the my objects were created on startup and they were "alive", therefore they were listening to the changes of itemSize. Now they listen only when they are visible, so they don't do the "something" I need because the changes have likely already happened (i.e. I read from settings file on startup).

One solution is to call a C++ method in the Component.onCompleted event to request the last update of the vars. It will work, but I will loose the benefits of the bound vars.

Is there any other smart way? I.e. force automagically the update of the bound variables on component load.

Upvotes: 0

Views: 665

Answers (1)

derM
derM

Reputation: 13711

In most cases you should not need the Component.onCompleted-event. If you need it, you would most likely have been in need of it already when you did not use the StackView.

Why? Because the probabillity is high, that you might refactor your code, in a way that you use bindings, rather than signal-handeling.
Of course, this might not be possible in any case, but (without proof) I would guess a number of 99% of cases where you did not need the Component.onCompleted-event should be possible to be refactored.

If you use the signal-handlers to set variables, (including the Component.onCompleted-signal) it tends to become more and more non-declarative, which you might try to avoid.

Setting the properties in event-handlers such as Component.onCompleted usually don't bind (unless you use Qt.binding(function() {return value}) which might lead to further issues.

Instead, if you need to react to a valueChanged-signal, consider triggering this in the Component.onCompleted manually, rather than initializing the value there, to avoid errors due to forgotten bindings.

Component.onCompleted: {
    somePropertyChanged()
    someOtherPropertyChanged()
    ......
}

But again: The first thin you should try, is to solve the problems by replacing the event-handling by binding (conditionaly) directly to the values.

Upvotes: 1

Related Questions