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/C++ signal slots help

QML/C++ signal slots help

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 2 Posters 509 Views 2 Watching
  • 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.
  • D Offline
    D Offline
    dij0nmustard
    wrote on last edited by
    #1

    Hi, relative coding newbie here.

    I'm using an app that combines QML and C++. I'm able to access a C++ object's functions and trigger them from a QML GUI, but I can't seem to use the Connections properly and get the onSignal process working correctly. Any advice would be greatly appreciated! I'm using Qt 5.15 on an embedded device.

    I am trying to get a signal (threadInitializeMainSuccess) to trigger a change in a qml GUI. However, when I trigger my mouseArea, the onSignal :{} functions trigger immediately rather than waiting until the signal actually fires.

    Here is the relevant portion of my main.cpp file:

    //int main stuff:
    System m_systemHandler; //instantiate the system class, named m_systemHandler to be passed to QML Engine and other classes. There will only be 1 "master" systemHandler that will be altered.
    threadController m_threadHandler(&m_systemHandler);
    
    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    
    QQmlContext *context(engine.rootContext());
    QQmlContext *context2(engine.rootContext());
    
    context->setContextProperty("systemHandler", &m_systemHandler);
    context2->setContextProperty("threadHandler", &m_threadHandler);
    
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
    return app.exec();
    }
    

    Here is the portion of my threadController.cpp file that sends the signal. This signal is tied to a motor - once it finishes initializing it sends a signal connected to this slot. If need be, I can include that file, but I didn't think it necessary since it is firing normally:

    void threadController::startInitializeMainThread()
    {
        qDebug("main initialize Thread called");
        QThread *mainInitializeQThread = new QThread(); //Pointer To QThread
        mainInitializeQThread->setObjectName("mainInitializeThread");
        motorController *mainInitializeMotor = new motorController(*m_systemHandler); //Create motorController instance and feed systemHandler into it.
        mainInitializeMotor->moveToThread(mainInitializeQThread);
    
        QObject::connect(mainInitializeMotor, &motorController::destroyMotorThreadInitMain, mainInitializeMotor, &motorController::deleteLater);
        QObject::connect(mainInitializeMotor, &motorController::destroyMotorThreadInitMain, mainInitializeQThread, &QThread::quit);
    
        QObject::connect(mainInitializeMotor, &motorController::motorInitializeMainSuccess, this, &threadController::mainSignalNotifier);
    
        QObject::connect(mainInitializeQThread, &QThread::finished, mainInitializeQThread, &QThread::deleteLater);
        QObject::connect(this, &threadController::userRequestStartInitializeMain, mainInitializeMotor, &motorController::initializeMain); 
        
        mainInitializeQThread->start();
    }
    
    void threadController::mainSignalNotifier()
    {
        emit threadInitializeMainSuccess();
    }
    

    And here is my .qml file with the GUI:

    import QtQuick 2.15
    
    Item {
        id: qsInitializeRoot
    
        property bool clientInitDone: false
        property bool serverInitDone: false
        property bool mainInitDone: false
        property bool telescopeInitDone: false
        property bool rotateInitDone: false
        property bool rollInitDone: false
    
    
        Connections {
            target: threadHandler
    
    //When I uncomment the following code, I get an "invalid property name" error. 
    
            //onClientInitDone { change clientInitDone to true.}
            //onServerInitDone { change serverInitDone to true.}
            //if (clientInitDone && serverInitDone) {Change stacker.source = homeview.qml}
    
        }
    
    
        function initializeWait() {
    
            onThreadInitializeMainSuccess: {
                displayer.color = "red"
                mainInitDone = true
                if (mainInitDone && telescopeInitDone) {
                    clientInitDone = true
                }
            }
    
            onThreadInitializeTelescopeSuccess: {
                displayer.color = "blue"
    
                telescopeInitDone = true
                if (mainInitDone && telescopeInitDone) {
                    clientInitDone = true
                }
            }
    
            onRollInitSuccess: {
                displayer.color = "green"
    
                rollInitDone = true
                if (rollInitDone && rotateInitDone) {
                    serverInitDone = true
                }
            }
    
            onRotateInitSuccess: {
                displayer.color = "black"
    
                rotateInitDone = true
                if (rollInitDone && rotateInitDone) {
                    serverInitDone = true
                }
            }
    
            if (clientInitDone && serverInitDone) {
                displayer.color = "purple"
    
                //stacker.source = "/ui/homeView.qml"
            }
    
        }
    
    
        Image {
            id: backgroundImage
            anchors.fill: parent
            source: "/images/initializeScreen"
    
            MouseArea {
                id: cursorHide
                anchors.fill: parent
                cursorShape: Qt.BlankCursor
    
                onClicked: {
                    cursorHide.enabled = false
                    backgroundImage.source = "/images/initializeScreen2"
                    initializeWait()
                    threadHandler.startInitializeThread()
                    threadHandler.startInitializeSocket()
    
    
                }
            }
    
            Rectangle {
                id: displayer
                anchors {
                    left: parent.left
                    right: parent.width/2
                    bottom:parent.height/2
                    top: parent.top
                }
    
               // anchors.fill: parent
                height: 150
                width: 150
    
    
                Text {
                    anchors.fill: parent
                    font.pixelSize: 50
                    text: "telescopeInit: " + telescopeInitDone
                          + "\n mainInitDone: " + mainInitDone
                          + "\n clientInitDone: " + clientInitDone
                          + "\n serverInitDone: " + serverInitDone
                          + "\n rollInitDone: " + rollInitDone
                          + "\n rotateInitDone: " + rotateInitDone
                }
            }
        }
    
    
    }
    
    

    Any advice would be super helpful! Thanks.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dij0nmustard
      wrote on last edited by
      #2

      I should also mention that the threadHandler.startInitializeThread() function in the .qml file calls the startMainInitializeThread() in the threadcontroller.cpp file successfully.

      Marko StankeM 1 Reply Last reply
      0
      • D dij0nmustard

        I should also mention that the threadHandler.startInitializeThread() function in the .qml file calls the startMainInitializeThread() in the threadcontroller.cpp file successfully.

        Marko StankeM Offline
        Marko StankeM Offline
        Marko Stanke
        wrote on last edited by Marko Stanke
        #3

        @dij0nmustard I think it would be a much simpler solution to move your onSignal functions directly inside the Connection of threadHandler, and if need be to change the enabled property of the connection when initializeWait() is triggered.

        Also some tips:

        1. New syntax for defining slots on qml is function on<SignalName>(params){}
        2. If working with threads, recommendation is to use Qt::QueuedConnection type.

        Final thing, i didn't try it out, but dynamically assigning connections from in qml looks something like this

        button.clicked.connect(function)
        

        Never tried it with C++ and QML, but maybe it would work. (Do not recommend this way)

        D 1 Reply Last reply
        0
        • Marko StankeM Marko Stanke

          @dij0nmustard I think it would be a much simpler solution to move your onSignal functions directly inside the Connection of threadHandler, and if need be to change the enabled property of the connection when initializeWait() is triggered.

          Also some tips:

          1. New syntax for defining slots on qml is function on<SignalName>(params){}
          2. If working with threads, recommendation is to use Qt::QueuedConnection type.

          Final thing, i didn't try it out, but dynamically assigning connections from in qml looks something like this

          button.clicked.connect(function)
          

          Never tried it with C++ and QML, but maybe it would work. (Do not recommend this way)

          D Offline
          D Offline
          dij0nmustard
          wrote on last edited by
          #4

          @Marko-Stanke Hi! Thanks for your reply. When I try moving the onSignal() {} into the Connection of threadHandler, I get an error saying "invalid property name". However, when I move the onSignal outside of the Connection, the program doesn't give me an error. Do you know why it's doing that?

          With regards to threads, I believe the .qml file and threadcontroller instance are running on the same main thread.

          Marko StankeM 1 Reply Last reply
          0
          • D dij0nmustard

            @Marko-Stanke Hi! Thanks for your reply. When I try moving the onSignal() {} into the Connection of threadHandler, I get an error saying "invalid property name". However, when I move the onSignal outside of the Connection, the program doesn't give me an error. Do you know why it's doing that?

            With regards to threads, I believe the .qml file and threadcontroller instance are running on the same main thread.

            Marko StankeM Offline
            Marko StankeM Offline
            Marko Stanke
            wrote on last edited by
            #5

            @dij0nmustard Not sure. Based on the code it looks fine.

            But maybe just in case, instead of making context and context2, try setting the contextProperty directly from the engine.

            If that doesn't work maybe you could try using
            qmlRegisterSingletonInstance instead of using Context, it is generally the preferred way anyway.

            D 1 Reply Last reply
            0
            • D dij0nmustard has marked this topic as solved on
            • Marko StankeM Marko Stanke

              @dij0nmustard Not sure. Based on the code it looks fine.

              But maybe just in case, instead of making context and context2, try setting the contextProperty directly from the engine.

              If that doesn't work maybe you could try using
              qmlRegisterSingletonInstance instead of using Context, it is generally the preferred way anyway.

              D Offline
              D Offline
              dij0nmustard
              wrote on last edited by
              #6

              @Marko-Stanke Thanks for the assistance. For some reason on my computer, it didn't sense the exposed object in Qt Creator - but on my raspberry pi it did. Not sure what I did differently.

              1 Reply Last reply
              1

              • Login

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