Home > Mobile >  How to not break bindings in qml?
How to not break bindings in qml?

Time:07-27

I currently have an image which becomes visible or not depending on some steps of a process. The qml code for that image is the following :

Image
{
    id : cameraDisplay

    visible : mainViewModel.getCurrentSegmentIsCameraDisplayed
    anchors.centerIn : parent
    source: "Images/Todo.png"
}

I also have a button, which the user can press to display that image or not :

Button
{
    Layout.fillWidth: true
    Layout.fillHeight: true
    buttonText : "CAMERA"
    onClicked: {cameraDisplay.visible = !cameraDisplay.visible;}
}

In the c , the binding looks like this :

Q_PROPERTY(bool getCurrentSegmentIsCameraDisplayed
    READ getCurrentSegmentIsCameraDisplayed
    NOTIFY segmentChanged)

the idea is that every time the current step of the process changes in my program, a notification is sent. That notification is then sent to the QML, which then gets the backend value to know if the camera should display or not that image.

I also have a button, which allows the user to toggle on or off the visibility of that image. The problem is that once that button is clicked, I lose the Q_PROPERTY binding, which means that once I go to the next segment, the notifications sent to the qml won't change the visibility of the image.

So basically, what I would want would be the following situation :

  1. The segment changes, a notification is sent to the qml, and the visiblity of the image is updated automatically.
  2. The user presses the button, which toggles the visibility of that image.
  3. The segment changes again, a notification is sent to the qml, and the visibility of that image is again updated according to the backend.

Currently, step 3 doesn't work. What should I change to make it work?

thanks

CodePudding user response:

You can change your binding in C to emit a signal when a change occurs, like this:

Q_PROPERTY(bool getCurrentSegmentIsCameraDisplayed 
           READ getCurrentSegmentIsCameraDisplayed 
           WRITE setCurrentSegment 
           NOTIFY segmentChanged)

In your class.h,

class MyClass : public QObject
{
    Q_OBJECT
    bool _segment;

public: 
    const bool &getCurrentSegmentIsCameraDisplayed() const;
public slots:
    void setCurrentSegment(const bool &newSegment);
signals:
    void segmentChanged(const bool &segment);
};

In your class.cpp,

void MyClass::setCurrentSegment(const bool &newSegment)
{
    if (_segment == newSegment){
        return;
    }else{
        _segment = newSegment;
        emit segmentChanged(_segment);

    }
}

const bool &MyClass::getCurrentSegmentIsCameraDisplayed() const
{
    return _segment;
}

Now in C you can change the process value any way you want. On the QML side, when you need to change the property, just use the SLOT setCurrentSegment passing its new state:

Image
{
    id : cameraDisplay
    visible: mainViewModel.getCurrentSegmentIsCameraDisplayed
    anchors.centerIn : parent
    source: "https://www.cleverfiles.com/howto/wp-content/uploads/2018/03/minion.jpg"
}

Button
{
    text : "CAMERA"
    onClicked: {
        mainViewModel.setCurrentSegment(!cameraDisplay.visible)
    }
}

The binding is maintained regardless of where the change takes place.

CodePudding user response:

I think you don't want your Button to directly change the visibility. You want it to change some other flag that the visibility depends on. How about something like this:

property bool showImage: true

Image
{
    id : cameraDisplay
    visible : showImage && mainViewModel.getCurrentSegmentIsCameraDisplayed
}

Button
{
    onClicked: {showImage = !showImage}
}
  • Related