Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML Signal/C++ Slot connect successful, but no result when signal emitted?

QML Signal/C++ Slot connect successful, but no result when signal emitted?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 3 Posters 601 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jjgccgJ Offline
    jjgccgJ Offline
    jjgccg
    wrote on last edited by jjgccg
    #1

    Hello everyone - I'm having an issue with a slot not being called despite a successful connection between the QML signal and the C++ slot.

    I have a custom QML on/off type of switch that looks like this.

    Rectangle {
        id: buttonRoot
        border.color: colorMain
        color: "#000000"
        anchors.horizontalCenter: parent.horizontalCenter
        
        property bool on: false
        
        function switchState() {
            if(on === true) {
                topHalf.color = "#8d8d8d"
                bottomHalf.color = "#5e5e5e"
                topHalfLabel.text = ""
                bottomHalfLabel.text = "OFF"
                on = false
            }
            else {
                topHalf.color = "#5e5e5e"
                bottomHalf.color = "#00FF11"
                topHalfLabel.text = "ON"
                bottomHalfLabel.text = ""
                on = true
            }
        }
        
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onClicked: switchState()
        }
        
        Column {
            anchors.centerIn: parent
            
            Rectangle {
                id: topHalf
                color: "#8d8d8d"
                width: buttonRoot.width
                height: buttonRoot.height / 2
                
                GlowingLabel {
                    id: topHalfLabel
                    color: "white"
                    font.pixelSize: 30
                    anchors.centerIn: parent
                }
            }
            
            Rectangle {
                id: bottomHalf
                color: "#5e5e5e"
                width: buttonRoot.width
                height: buttonRoot.height / 2
                
                GlowingLabel {
                    id: bottomHalfLabel
                    text: qsTr("OFF")
                    color: "white"
                    font.pixelSize: 30
                    anchors.centerIn: parent
                }
            }
        }
    }
    

    This switch is used in a few different places, so I just put it in its own QML file, and then when I want to use it I just declare SwitchButton{} and change the dimensions if I need to.

    What I'm trying to do now is put an extra MouseArea on an instance of the SwitchButton, so when the button is clicked, not only does it turn on/off, but also emits a signal that is captured by a slot backend. The backend slot should change labels on the QML front end, for example: Pressure should go from 0 PSI in an off state, to 64 PSI in an on state.

    Here is what my instance of the SwitchButton looks like:

                SwitchButton {
                    id: generatorSwitch
                    objectName: "generatorSwitch"
                    width: 120
                    height: 145
                    
                    signal qmlSignal(bool generatorState)
                    
                    MouseArea {
                        anchors.fill: parent
                        propagateComposedEvents: true
                        onClicked: {
                            mouse.accepted = false
                            generatorSwitch.qmlSignal(generatorSwitch.on)
                        }
                    }
                }
    

    As you can see, qmlSignal(bool generatorState) sends whether the generator switch is ON/OFF to the backend code.

    In the C++ backend, I'm creating a QQmlComponent with the parent file, passing this object to a class which handles the changing of the ON/OFF values (GeneratorControl), and then forming a connection between the signal and slot.

        // Hook up signals and slots for integration with QML
        QQmlComponent component(&engine, QUrl("qrc:/qml/root.qml"));
        if(component.status() == component.Ready) {
            QObject* object = component.create();
    
            // GENERATOR ON/OFF SWITCH
            GeneratorControl generatorControl(object);
            QObject* generatorSwitch = object->findChild<QObject*>("generatorSwitch");
            bool res = QObject::connect(generatorSwitch, SIGNAL(qmlSignal(bool)),
                             &generatorControl, SLOT(generatorPower(bool)));
            qDebug() << res;
        }
    

    Here is the slot inside of the GeneratorControl instance, which should at least print either "power on" or "power off" when the switch is clicked in QML.

    void GeneratorControl::generatorPower(bool powerState)
    {
        if(powerState == true)
        {
            qDebug() << "power on";
            powerOnGenerator();
        }
        else
        {
            qDebug() << "power off";
            powerOffGenerator();
        }
    }
    

    However, nothing is printed out. The connection between the signal and slot is successful - the result of res is true, and I get no signal/slot connection errors in the console. But the code inside of the generatorPower() slot is never executed when flipping the switch ON/OFF.

    Any ideas? I think it might have something to do with the two MouseArea on the QML switch, but I'm not sure.

    Thank you.

    1 Reply Last reply
    0
    • mranger90M Offline
      mranger90M Offline
      mranger90
      wrote on last edited by
      #2

      Could it be because your GeneratorControl object is in the scope of the "if" statement, and therefore no longer exists when the scope terminates ?

      jjgccgJ 1 Reply Last reply
      3
      • mranger90M mranger90

        Could it be because your GeneratorControl object is in the scope of the "if" statement, and therefore no longer exists when the scope terminates ?

        jjgccgJ Offline
        jjgccgJ Offline
        jjgccg
        wrote on last edited by jjgccg
        #3

        @mranger90 That was it! I got around this by using a Qt smart pointer to control the scope:

            // Hook up signals and slots for integration with QML
            QQmlComponent component(&engine, QUrl("qrc:/qml/hep.qml"));
            QObject* generatorSwitch;
            QScopedPointer<GeneratorControl> generatorControl;
            if(component.status() == component.Ready) {
                QObject* object = component.create();
        
                // GENERATOR ON/OFF SWITCH
                generatorControl.reset(new GeneratorControl(object));
                generatorSwitch = object->findChild<QObject*>("generatorSwitch");
                bool res = QObject::connect(generatorSwitch, SIGNAL(qmlSignal(bool)),
                                 generatorControl.data(), SLOT(generatorPower(bool)));
                qDebug() << res;
            }
        
        Pablo J. RoginaP 1 Reply Last reply
        0
        • jjgccgJ jjgccg

          @mranger90 That was it! I got around this by using a Qt smart pointer to control the scope:

              // Hook up signals and slots for integration with QML
              QQmlComponent component(&engine, QUrl("qrc:/qml/hep.qml"));
              QObject* generatorSwitch;
              QScopedPointer<GeneratorControl> generatorControl;
              if(component.status() == component.Ready) {
                  QObject* object = component.create();
          
                  // GENERATOR ON/OFF SWITCH
                  generatorControl.reset(new GeneratorControl(object));
                  generatorSwitch = object->findChild<QObject*>("generatorSwitch");
                  bool res = QObject::connect(generatorSwitch, SIGNAL(qmlSignal(bool)),
                                   generatorControl.data(), SLOT(generatorPower(bool)));
                  qDebug() << res;
              }
          
          Pablo J. RoginaP Offline
          Pablo J. RoginaP Offline
          Pablo J. Rogina
          wrote on last edited by
          #4

          @jjgccg said in QML Signal/C++ Slot connect successful, but no result when signal emitted?:

          That was it!

          Glad your issue is solved. Please don't forget to mark you post as such. Thanks

          Upvote the answer(s) that helped you solve the issue
          Use "Topic Tools" button to mark your post as Solved
          Add screenshots via postimage.org
          Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved