Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. signals from worker object never reach controller object?
Forum Updated to NodeBB v4.3 + New Features

signals from worker object never reach controller object?

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 5 Posters 746 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
    davecotter
    wrote on last edited by davecotter
    #1

    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

    1 Reply Last reply
    1
    • KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by KroMignon
      #3

      @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

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      1 Reply Last reply
      5
      • hskoglundH Offline
        hskoglundH Offline
        hskoglund
        wrote on last edited by
        #2

        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.

        1 Reply Last reply
        1
        • KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by KroMignon
          #3

          @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

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          1 Reply Last reply
          5
          • D Offline
            D Offline
            davecotter
            wrote on last edited by davecotter
            #4

            @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

            KroMignonK 1 Reply Last reply
            0
            • D davecotter

              @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

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by KroMignon
              #5

              @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

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              J.HilkJ 1 Reply Last reply
              3
              • KroMignonK KroMignon

                @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

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by J.Hilk
                #6

                @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


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                KroMignonK 1 Reply Last reply
                0
                • J.HilkJ J.Hilk

                  @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

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #7

                  @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?

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  J.HilkJ 1 Reply Last reply
                  2
                  • KroMignonK KroMignon

                    @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?

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #8

                    @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


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    kshegunovK 1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      @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

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #9

                      @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.

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      2
                      • D Offline
                        D Offline
                        davecotter
                        wrote on last edited by
                        #10

                        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!!!

                        1 Reply Last reply
                        2

                        • Login

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