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

signals from worker object never reach controller object?



  • i have an AudioWorker (optionally on a background thread), and i connected it to the AudioTest controller running on the main thread, like this:

    connect(
    	this,		&AudioWorker::updateControl,
    	audioTestP,	&AudioTest::updateControl,
    	Qt::QueuedConnection);
    

    yet if i attempt this from the worker object:

    emit updateControl(kControl_VOLUME_SLIDER, logVolume);
    

    the AudioTest slot in the controller object never gets called. which means the button names in the UI never update

    Here is a minimum compileable example:
    http://kjams.com/downloads/audiotest.zip

    note in the example, i commented out this line:

    m_audioWorkerP->moveToThread(&m_workerThread);
    

    to see if it would help, and strangely the signals STILL don't reach the slots?
    what am i missing here?

    The top button toggles between push and pull, and the bottom button toggles pause/resume. they work, but the text never gets updated due to the signals from the worker object never reaching the slots in the controller object



  • @davecotter Hello, I have took a quick look to your code and I think I found what the problem is.

    Have you check the connect statement did work?
    I don't think so, because your signal is using an enum as parameter (ControlType).
    You have to register first this enum, so Qt can serialized the data. If you don't do that, you cannot use QueuedConnection:

    qRegisterMetaType<ControlType>("ControlType");
    

    After that, it will work as expected.

    ==> take a look at documentation: https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1



  • Hi, you'll get the button texts updated if you do a vanilla connect() instead of a Qt::QueuedConnection on line 345 in audiooutput.cpp, i.e. in AudioWorkers constructor:

    AudioWorker::AudioWorker(AudioTest *audioTestP) :
    	m_pushTimer(new QTimer(this))
    {
    	m_curVolume = LogToLinVol(50);
    
    	connect(
                this,  	&AudioWorker::updateControl,
                audioTestP, &AudioTest::updateControl);
    //		Qt::QueuedConnection);
    }
    

    If you comment out the Qt::QueuedConnection the connect will work.



  • @davecotter Hello, I have took a quick look to your code and I think I found what the problem is.

    Have you check the connect statement did work?
    I don't think so, because your signal is using an enum as parameter (ControlType).
    You have to register first this enum, so Qt can serialized the data. If you don't do that, you cannot use QueuedConnection:

    qRegisterMetaType<ControlType>("ControlType");
    

    After that, it will work as expected.

    ==> take a look at documentation: https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1



  • @hskoglund i probably should have mentioned i had already attempted a "plain vanilla" connect, to no avail. it does seem more correct to have it be queued, since it may be on another thread anyway.

    @KroMignon yes, the return value of the connect() call does read as true when cast to bool. Separately, i have tried to call qRegisterMetaType(), but that doesn't cause the signals to make it to the slots.

    Have either of you (or anyone?) tried actually running the code provided? It's quite simple and will compile and run quite easily.

    -dave



  • @davecotter said in signals from worker object never reach controller object?:

    Have either of you (or anyone?) tried actually running the code provided? It's quite simple and will compile and run quite easily.

    Yes, I did it in the way I say it to you:

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        app.setApplicationName("Audio Output Test");
    
        qRegisterMetaType<ControlType>("ControlType");
        AudioTest audio;
        audio.show();
    
        return app.exec();
    }
    

    Without qRegisterMetaType<>():
    48d8772c-2c0d-4fd8-9ecf-f98d8896d888-image.png

    And with qRegisterMetaType<>():
    e4706301-f926-4e7b-a825-5c5066b05471-image.png


  • Moderators

    @KroMignon
    I did test it and I got the reason/error printed in my output

    4f05e4a5-ec9e-4300-847f-888da8aba910-image.png

    just as @KroMignon said, you need to register the enum with the meta system

    what I did:

    AudioWorker::AudioWorker(AudioTest *audioTestP) :
        m_pushTimer(new QTimer(this))
    {
        qRegisterMetaType<ControlType>("ControlType");
        m_curVolume = LogToLinVol(50);
    
        connect(
            this,		&AudioWorker::updateControl,
            audioTestP,	&AudioTest::updateControl,
            Qt::QueuedConnection);
    }
    

    and more important:

    typedef enum {
        kControl_PUSH_PULL_BUTTON,
        kControl_SUSPEND_RESUME_BUTTON,
        kControl_OUT_DEVICE_MENU,
        kControl_VOLUME_SLIDER
    } ControlType;
    
    //----------------------------------------------------------------------------------
    class AudioTest;
    
    class AudioWorker : public QObject {
        Q_OBJECT
    
        Q_ENUM(ControlType)////<-------
    

    The Q_ENUM macro is vital as well see posts below



  • @J-Hilk said in signals from worker object never reach controller object?:

    The Q_ENUM macro is vital as well

    Why is Q_ENUM vital?
    For my understanding, Q_ENUM only made sense when the enum is inside the class.
    Did I miss something?


  • Moderators

    @KroMignon

    You're right juts tested it without it. I though it was vital and I always write it 😇

    But it seem to work here just as fine without it


  • Moderators

    @J-Hilk said in signals from worker object never reach controller object?:

    I though it was vital and I always write it

    For a global enum, you should not. A global enum you declare with Q_DECLARE_METATYPE and register as @KroMignon mentioned. If it's aliased the aliased name is required, if not the usual call without a string argument is appropriate.



  • my apologies for the extra goose-chasing.

    the suggestion by @KroMignon was in fact correct, i had mistyped it in a way that did compile but was incorrect, so my conclusion was wrong.

    thanks everyone for your great help!!!


Log in to reply