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

Wait until slot end to continue program execution



  • Hello, I'm working on a CanBus API. I 'm storing received data from my device in a QStringList. There i connect the signal QCanBusBusFrame::Received frame to a slot processFrame.
    The problem is when i read the QStringList in my main function it is empty. Seconds after it is filled.
    Here is my connection and code:

    void DevicesManagement::processReceivedFrames()
    {
        if(!m_device)
            return;
        while (m_device->framesAvailable()) {
            const QCanBusFrame frame = m_device->readFrame();
            m_receivedFrames.append(frame.payload().toHex());
            set_deviceProfile(frame.payload().toHex().right(8).toUpper());
        }
        emit processOver();
        qDebug()<<get_deviceProfile();
        disconnect();
    }
    

    And i connected my slot to the signal like this:

        connect(m_device, &QCanBusDevice::framesReceived, this, &DevicesManagement::processReceivedFrames);
    
    

    And there is my main

    int main (int argc, char * argv []) {
        QGuiApplication app (argc, argv);
        QQmlApplicationEngine engine (&app);
        registerQtQmlTricksUiElements (&engine);
        registerQtQmlTricksSmartDataModel (&engine);
        DevicesManagement *manager=new DevicesManagement(&engine);
        QList<QObject*>mDeviceList;
        manager->initializeDevices("125000");
        manager->deviceProfileProcess();
        qDebug()<<manager->get_deviceProfile();
     
    
        engine.load (QUrl ("qrc:///splash_power.qml"));
    
        return app.exec ();
    }
    
    

    The problem is that my slot processReceivedFrames is not over yet when i read my frame. Therefore it is empty.
    Anyone got an idea to solve that issue?


  • Qt Champions 2019

    @Babs said in Wait until slot end to continue program execution:

    qDebug()<<manager->get_deviceProfile();

    Do you mean it is empty here?



  • @jsulm yes and it is filled when my slot ends


  • Qt Champions 2019

    @Babs But why do you need to read it there?
    Correct way would be to emit a signal from DevicesManagement when the list is complete and read it in the slot.



  • @jsulm I use it to create an Object that i will expose to qml



  • @Babs here is what i do next in my main

    int main (int argc, char * argv []) {
        QGuiApplication app (argc, argv);
        QQmlApplicationEngine engine (&app);
        registerQtQmlTricksUiElements (&engine);
        registerQtQmlTricksSmartDataModel (&engine);
        DevicesManagement *manager=new DevicesManagement(&engine);
        QList<QObject*>mDeviceList;
        manager->initializeDevices("125000");
        manager->deviceProfileProcess();
        qDebug()<<manager->get_deviceProfile();
        CanOpenDevice *dev1=new CanOpenDevice(23,manager->get_deviceProfile(),&engine);
        mDeviceList.append(dev1);
        qmlRegisterType<CanOpenDevice>("com.device",1,0,"CanDevice");
        engine.rootContext()->setContextProperty("mManager",manager);
        engine.rootContext()->setContextProperty("mModel",QVariant::fromValue(mDeviceList));
    
    
        engine.load (QUrl ("qrc:///splash_power.qml"));
    
        return app.exec ();
    }
    

  • Qt Champions 2019

    @Babs You're trying to program synchronously using an asynchronous framework. You really should do it in an asynchronous way. Using signals/slots. Connect a slot in CanOpenDevice to a signal in DevicesManagement which is emitted when the list is filled.



  • @jsulm thank you i'll try to do so. I thought i could may be suspend my main thread until my variable is filled


  • Moderators

    @Babs

    lambdas are your friend ;-)

    QObject::connect(manager, &DevicesManagement::devicesReady, &engine, [&engine, & mDeviceList](QStringList list)->void{
          qDebug()<< list;
        CanOpenDevice *dev1=new CanOpenDevice(23, list,&engine);
        mDeviceList.append(dev1);
        engine.rootContext()->setContextProperty("mManager",manager);
        engine.rootContext()->setContextProperty("mModel",QVariant::fromValue(mDeviceList));     
    });
    engine.load (QUrl ("qrc:///splash_power.qml"));
    
        return app.exec ();
    

    should work, fine.

    But it's untested.



  • @J.Hilk Thanks you. Its works.
    Regards.


Log in to reply