johnbakers
johnbakers

Reputation: 24771

Is emitting a signal from C++ to QML for reading a Q_PROPERTY a synchronous event?

Using Qt 5.1 I have this:

Q_PROPERTY(float d1 MEMBER data1 NOTIFY datas_changed_signal)
Q_PROPERTY(float d2 MEMBER data2 NOTIFY datas_changed_signal)

....

void setOBJ(nobj){
        obj=nobj; //these are pointers to a data structure
        data1=nobj->data1(); //assign to member of this class
        data2=nobj->data2();

        emit datas_changed_signal();
    }

My class receives a pointer to some data, nobj and then I want my QML to have access to this data. Actually nobj contains far more than just 2 data items, but I express here for simplicity.

I want to know a couple things. First, what happens when setOBJ is called often, quickly. Is there a risk that the QML will get notified but not read the MEMBER (data1 or data2) before setOBJ is called again? Could the QML miss some updates because of this? This would happen if it was asynchronous, for example. Or, can I always count on the QML getting the data every time this signal above it emitted?

Second, it seems to me there is some unnecessary overhead here in creating intermediate data members to store the data from the passed-in object nobj. I tried this instead:

    Q_PROPERTY(float d1 MEMBER obj->data1() NOTIFY datas_changed_signal)

But MOC doesn't seem to like using Q_PROPERTY in this way (doesn't compile). Would there be a similar alternative?

Update: I found this method (link) that seems like a viable alternative to Q_PROPERTY for sending data from C++ to QML, I could just send my data pieces as arguments to a QML function. Is that a good alternative?

Upvotes: 4

Views: 1961

Answers (1)

Wes Hardaker
Wes Hardaker

Reputation: 22262

Signals and slots are implemented synchronously, by default, and are always processed in order even when implemented asynchronously and even passed across thread boundaries. So you don't need to worry that your QML will be getting the signals in the wrong order.

And, in fact, by default signals actually fire off all the bound object code immediately. IE, this:

emit datas_changed_signal();

Is almost like calling:

slotFunction1();
slotFunction2();
...

So any attached QML javascript (onDatas_changed_signal) will be called immediately, in fact.

Signals and slots are the preferred way to send data to QML, as it provides much greater support for QML being independent from the C++ underlying model, so I'd stick with properties, signals and slots. Your QML code may someday need to expand and have multiple things happen on a propery change, and that's simply easy and slick if you do it via a property rather than calling a QML function directly.

Upvotes: 4

Related Questions