Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 QML signal 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()")
    }
    


  • @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 believe this modelData is actually stemming from a model: property somehow... sorry this is all rather new to me, trying to catch on here. I think this application is using C++ plugins somehow.



  • I think I am understanding how to connect to these signals. This "presenter" has Q_Property's which make connections with these signals 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 the Q_PROPERTY shown above is it's corresponding slot, is that correct?



  • 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


Log in to reply