PDA

View Full Version : Q_PROPERTY WRITE with slot between Threads



EMCEE
15th August 2012, 12:05
Hello,

I'm having issues with Qt's Property System.

Basically i am trying to write a Q_PROPERTY of a Object that lives in a different thread. I'm doing this from QML. I was thinking, that if i declare the WRITE function as a slot, that function will be invoked in the Event Loop of the other Thread. Sadly this is not happening.

I made i minimal Example for Windows which shows the Problem.

How can i make the WRITE accessor function being invoked in the event loop? I'm using QT 4.7.4

Oleg
15th August 2012, 13:48
QML seems to use Qt::DirectConnection only. If this is an issue, you can go a little hacky and create custom signal in QML object, and then connect to it from C++ specifying Qt::QueuedConnection.

EMCEE
15th August 2012, 15:09
QML seems to use Qt::DirectConnection only. If this is an issue, you can go a little hacky and create custom signal in QML object, and then connect to it from C++ specifying Qt::QueuedConnection.

Ok this is a possibility. I updated the example. Now i'm using a Signal as the WRITE accessor function, which calls the real slot.

But i really dont like the idea of having to declare such Signals all over my Project.

Will this be changed in future Qt versions?

Oleg
15th August 2012, 15:24
File an issue on Qt bug tracker and explain your use-case. I'm not sure if QML should be aware of signal receiver thread.

high_flyer
15th August 2012, 16:13
class MyQobjectClass : public QObject {
Q_OBJECT
Q_PROPERTY(int someValue READ getValue WRITE setValueInvoker NOTIFY valueChanged) //using a signal as a setter didn't you mean to use setValue()?

public:
explicit MyQobjectClass(QObject *parent = 0);

public slots:
void setValue(int newValue);
int getValue();

signals:
void setValueInvoker(int); //<<--- signal
void valueChanged();

private:
int value;

You use a signal as a setter.

EMCEE
15th August 2012, 16:36
class MyQobjectClass : public QObject {
Q_OBJECT
Q_PROPERTY(int someValue READ getValue WRITE setValueInvoker NOTIFY valueChanged) //using a signal as a setter didn't you mean to use setValue()?

public:
explicit MyQobjectClass(QObject *parent = 0);

public slots:
void setValue(int newValue);
int getValue();

signals:
void setValueInvoker(int); //<<--- signal
void valueChanged();

private:
int value;

You use a signal as a setter.


Exactly. And it is connected to the setValue(int) slot. So the slot is invoked in a the other thread.

Look at the attachment of the first post!

Added after 4 minutes:


File an issue on Qt bug tracker and explain your use-case. I'm not sure if QML should be aware of signal receiver thread.

Yes, seems like it isnt aware of the receiver thread. Direct Connection is also used, when i call a slot or Q_INVOKABLE directly from QML.

tescrin
15th August 2012, 17:02
Depending on how it's designed you could use static data, which should be shared between threads (So to speak.)

Much cleaner and faster.

high_flyer
15th August 2012, 17:15
Exactly. And it is connected to the setValue(int) slot. So the slot is invoked in a the other thread.
My point was, that I am not sure if the setter called by Q_PROPERTY actually will *emit* the signal, rather then juts call it as a call back (function pointer) - and since a signal has no definition, it just probably will do nothing.
But if you actually do get the signal invoked at all (no matter in what thread) then ok.

To solve your problem however you can have a regular setter invoke your signal as Qt::QueuedConnection.