Q_INVOKABLE vs signal from QML to C++: Best practice
-
Hi,
I wonder what is the best way about connecting my qml ui with my c++ backend. Often, I was using Q_INVOKABLE functions directly in qml, e.g. if I would have abutton which says start, I would call the Q_INVOKABLE function start instead of sending a signal and connecting it to a start slot.
What is considered the best practice with respect to code architecture?
-
I don't think either is considered good or bad - both solutions work and make sense. Pick whatever feels better to you in that particular project.
-
Hi,
I wonder what is the best way about connecting my qml ui with my c++ backend. Often, I was using Q_INVOKABLE functions directly in qml, e.g. if I would have abutton which says start, I would call the Q_INVOKABLE function start instead of sending a signal and connecting it to a start slot.
What is considered the best practice with respect to code architecture?
@maxwell31 There are no really good or bad about
Q_INVOKABLE
orQ_PROPERTY
(signals/slots). It depends what you want to achieve.
UsingQ_INVOKABLE
gives you the possibility to have return value, which is not possible withsignals
, for example. But in the other hand, withsignals
you can ensure function is called in the right thread, withQ_INVOKABLE
it will be executed in the QML thread.So, as I written before, it depends on your use case!
-
@KroMignon
Is the qml-thread different from the thread where the object having the q_invokable as a member is living?I am asking this because we had some discussions about using a Q_INVOKABLE breaking encapsulation.
To me it feels more natural using a Q_INVOKABLE as you immedeatly see what a button will do, and otherwise you need to check the connection first. Another developer was arguing that using Q_INVOKABLE is bad because it forces you to know the C++ structure in QML. My view is that using signals and doing the connection forces you to know the UI structure in C++, which I consider worse
-
@KroMignon
Is the qml-thread different from the thread where the object having the q_invokable as a member is living?I am asking this because we had some discussions about using a Q_INVOKABLE breaking encapsulation.
To me it feels more natural using a Q_INVOKABLE as you immedeatly see what a button will do, and otherwise you need to check the connection first. Another developer was arguing that using Q_INVOKABLE is bad because it forces you to know the C++ structure in QML. My view is that using signals and doing the connection forces you to know the UI structure in C++, which I consider worse
@maxwell31 said in Q_INVOKABLE vs signal from QML to C++: Best practice:
Is the qml-thread different from the thread where the object having the q_invokable as a member is living?
I would reply to this with "it depends" ;-)
With some QML backends, the QML Engine is using 2 thread to work: one thread to prepare the display and one thread to do the display.
And on C++ side, it is up to you to decide in which thread the QObject is living!
So yes, there is no absolut garantie QML and you C++ object instance are living in same thread.Take a look at the webinar about QML / C++ to get some good ideas about how to separate QML and C++: https://resources.qt.io/qt-virtual-tech-con-2020/c-to-qml-animations-12th-may-12-pm-pst
-
@KroMignon
Is the qml-thread different from the thread where the object having the q_invokable as a member is living?I am asking this because we had some discussions about using a Q_INVOKABLE breaking encapsulation.
To me it feels more natural using a Q_INVOKABLE as you immedeatly see what a button will do, and otherwise you need to check the connection first. Another developer was arguing that using Q_INVOKABLE is bad because it forces you to know the C++ structure in QML. My view is that using signals and doing the connection forces you to know the UI structure in C++, which I consider worse
@maxwell31 If unsure, it's not a bad idea to log the thread with
QObject::thread()
. That's what I did. It's not a thread ID, just a pointer value.