Question on signals and communicating between c++ and QML
-
How do I detect emits in the back-end and base logic in the front end off of them? For instance, if I have a signal that's emitted in the back-end every time a mode changes:
void GuidancePresenter::setMode(Mode mode) { if (m_currentMode == mode) { return; } m_currentMode = mode; switch (m_currentMode) { case GuidanceMode: m_currentState = &m_guidanceState; break; case BoundaryMode: m_currentState = &m_boundaryState; break; case ObstacleMode: m_currentState = &m_obstacleState; break; default: m_currentState = nullptr; break; } rebuildQuickAccessBar(); emit modeChanged(); }
how do I go about basing my front-end logic off of that change? For instance, if I want the
text:
property of something to change it's text whenever the signal is emitted? Is that what the QMLsignal
property is used for? I looked at the documentation for it and that doesn't seem to be the case. -
How do I detect emits in the back-end and base logic in the front end off of them? For instance, if I have a signal that's emitted in the back-end every time a mode changes:
void GuidancePresenter::setMode(Mode mode) { if (m_currentMode == mode) { return; } m_currentMode = mode; switch (m_currentMode) { case GuidanceMode: m_currentState = &m_guidanceState; break; case BoundaryMode: m_currentState = &m_boundaryState; break; case ObstacleMode: m_currentState = &m_obstacleState; break; default: m_currentState = nullptr; break; } rebuildQuickAccessBar(); emit modeChanged(); }
how do I go about basing my front-end logic off of that change? For instance, if I want the
text:
property of something to change it's text whenever the signal is emitted? Is that what the QMLsignal
property is used for? I looked at the documentation for it and that doesn't seem to be the case.@Circuits said in Queston on signals and communicating between c++ and QML:
how do I go about basing my front-end logic off of that change?
your QML needs to know about your GuidancePresenter object (Embedd it into QML Context ), then you will be able to detect signals
see here
https://doc.qt.io/qt-5/qtqml-cppintegration-overview.html@Circuits said in Queston on signals and communicating between c++ and QML:
Is that what the QML signal property is used for?
No, qml signal is same as c++ signal, its just a signal. QML Connections is more for that
id: someComponent signal mySignal() ... onClicked : mySignal() ... onMySignal : console.log("my signal fired") Connections { target: someComponent onMySignal: console.log("qml connection catched mySignal()") }
-
@Circuits said in Queston on signals and communicating between c++ and QML:
how do I go about basing my front-end logic off of that change?
your QML needs to know about your GuidancePresenter object (Embedd it into QML Context ), then you will be able to detect signals
see here
https://doc.qt.io/qt-5/qtqml-cppintegration-overview.html@Circuits said in Queston on signals and communicating between c++ and QML:
Is that what the QML signal property is used for?
No, qml signal is same as c++ signal, its just a signal. QML Connections is more for that
id: someComponent signal mySignal() ... onClicked : mySignal() ... onMySignal : console.log("my signal fired") Connections { target: someComponent onMySignal: console.log("qml connection catched mySignal()") }
@LeLev This is what I find confusing. There are portions of this QML where I can access an object called modelData, for instance:
Connections { target: modelData onValueChanged: //here is a signal from the back-end onSettingInvalidChanged: //here is another }
and there are portions where I can't, for instance, in main if I try to establish a connection to modelData:
qrc:/Source/QML/Main.qml:344: ReferenceError: modelData is not defined
and the documentation would seem to suggest that somewhere in the back-end, there would need to be a class called ModelData; however, no ModelData class exists. So I am a bit confused.
-
@LeLev This is what I find confusing. There are portions of this QML where I can access an object called modelData, for instance:
Connections { target: modelData onValueChanged: //here is a signal from the back-end onSettingInvalidChanged: //here is another }
and there are portions where I can't, for instance, in main if I try to establish a connection to modelData:
qrc:/Source/QML/Main.qml:344: ReferenceError: modelData is not defined
and the documentation would seem to suggest that somewhere in the back-end, there would need to be a class called ModelData; however, no ModelData class exists. So I am a bit confused.
@Circuits said in Queston on signals and communicating between c++ and QML:
onValueChanged: //here is a signal from the back-end
Being too strict, onValueChanged is not a signal; it's a signal handler: the entry point to some code that will execute when some signal (valueChanged in this example) is emitted.
And that signal can be emitted by "the back-end" (a C++ object) or a QML element, it will depend on your code. -
I think I am understanding how to connect to these signals. This "presenter" has
Q_Property
's which make connections with thesesignals
for instance:Q_PROPERTY(bool isGuidanceMode READ isGuidanceMode NOTIFY isGuidanceModeChanged)
So, on the QML side, if I want to define a string based on whether or not GuidanceMode is on or off then I would say something like:
presentationManager.guidancePresenter.isGuidanceMode ? "Guidance Mode On" : "Guidance Mode Off"
So I believe then that for the following example code:
void GuidancePresenter::setGuidanceMode(bool value) { if (m_isGuidanceMode != value) { m_isGuidanceMode = value; emit isGuidanceModeChanged(); } }
that the
emite isGuidanceModeChanged();
is the signal and theQ_PROPERTY
shown above is it's corresponding slot, is that correct? -
How do I detect emits in the back-end and base logic in the front end off of them? For instance, if I have a signal that's emitted in the back-end every time a mode changes:
void GuidancePresenter::setMode(Mode mode) { if (m_currentMode == mode) { return; } m_currentMode = mode; switch (m_currentMode) { case GuidanceMode: m_currentState = &m_guidanceState; break; case BoundaryMode: m_currentState = &m_boundaryState; break; case ObstacleMode: m_currentState = &m_obstacleState; break; default: m_currentState = nullptr; break; } rebuildQuickAccessBar(); emit modeChanged(); }
how do I go about basing my front-end logic off of that change? For instance, if I want the
text:
property of something to change it's text whenever the signal is emitted? Is that what the QMLsignal
property is used for? I looked at the documentation for it and that doesn't seem to be the case.HI @Circuits,
You need to pass your class object from cpp to qml
In mail.cpp:GuidancePresenter cppObject; view.rootContext()->setContextProperty("varName", &cppObject);
then in your qml just do it as follows.
import QtQuick 2.9 Item{ Connections{ target: varName // In QML for each signal you have a handler in the form "onSignalName" onYourSignal:{ // the arguments passed are implicitly available, named as defined in the signal // If you don't know the names, you can access them with "arguments[index]" console.log(i,t); // Do whatever in qml side //in your case, you need to change the text yourTextId.text="your text"; } } }
You can follow this link.
Happy coding