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. Weird issue with SIGNAL/SLOT
Forum Updated to NodeBB v4.3 + New Features

Weird issue with SIGNAL/SLOT

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 968 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.
  • L leinad

    Hi,
    I've been using signal and slots mostly between processes running under multiple threads but now I'm try instantiate two classes under a signal thread and using signal/slot to communicate between them. But for some reason the slot from one object is not being received from the other. Here is an example.

    I'm creating a thread in a class:

    #include "PluginWorker.h"
    
    void StartThread::startThread()
    {
        std::cout << "STARTING THREAD" << std::endl;
    
        QThread* pluginWorkerThread = new QThread;
        pluginWorkerThread->setObjectName("pluginWorkerThread");
        PluginWorker *pluginWorker = new PluginWorker;
        pluginWorker->moveToThread(pluginWorkerThread);
        
        connect(pluginWorker, SIGNAL(finished()), pluginWorkerThread, SLOT(quit()));
        connect(pluginWorker, SIGNAL(finished()), pluginWorker, SLOT(deleteLater()));
        connect(pluginWorkerThread, SIGNAL(finished()), pluginWorkerThread, SLOT(deleteLater()));
        connect(this, SIGNAL(sendExit()), pluginWorker, SLOT(receiveExit()), Qt::DirectConnection);
    
        pluginWorkerThread->start();
    }
    

    Once the thread is started using this call from another class

    startThread_ = new StartThread();
    startThread_->startThread();
    

    The thread does indeed start so far it is ok.
    In the pluginWorker class which runs under the above thread, I instantiate 2 classes as follows:

    PluginWorker::PluginWorker() :
       selectdatabase_(nullptr)
      ,databaseProcessing_(nullptr)
    {
        std::cout << "STARTING PLUGIN WORKER" << std::endl;
    
        databaseProcessing_ = new DatabaseProcessing(); 
        selectdatabase_ = new SelectDatabase();
    
        //setup communication between selectdatabase_ and databaseProcessing_
        connect(selectdatabase_, SIGNAL(sendDatabaseName(QString)), databaseProcessing_, SLOT(getDatabaseName(QString)));
    
    }
    

    However when I emit from selectDatabase::sendDatabaseName to the slot in databaseProcessing::getDatabaseName nothing is received.

    I'm using Q_Object in both classes for selectDatabase_ and databaseProcessing_

    Below is a include example, both are similar:

    #ifndef DATBASEPROCESSING_H
    #define DATBASEPROCESSING_H
    
    #include <QObject>
    #include <QMainWindow>
    
    class DatabaseProcessing : public QObject
    {
        Q_OBJECT
    
    public:
        DatabaseProcessing();
        virtual ~DatabaseProcessing();
    
    
    public Q_SLOTS:
        void getDatabaseName(QString databaseName);
    };
    

    Would anyone have any idea why the slot is not being called? I really would appreciate any feedback.

    Thanks!

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #2

    @leinad
    Hi. I see you have posted quite a lot in this forum. Would you care to start marking your code blocks inside the forum's Code tags? It's the icon which looks like </>, or put a line of ``` (3 backticks) above and below your blocks. You could edit your post. For my part it would make it a lot easier to see what's going on in your post.

    However when I emit from selectDatabase::sendDatabaseName to the slot in databaseProcessing::getDatabaseName nothing is received.

    Why don't you start by connecting a lambda to the signal so that you know that it's being emitted?

    L 1 Reply Last reply
    0
    • JonBJ JonB

      @leinad
      Hi. I see you have posted quite a lot in this forum. Would you care to start marking your code blocks inside the forum's Code tags? It's the icon which looks like </>, or put a line of ``` (3 backticks) above and below your blocks. You could edit your post. For my part it would make it a lot easier to see what's going on in your post.

      However when I emit from selectDatabase::sendDatabaseName to the slot in databaseProcessing::getDatabaseName nothing is received.

      Why don't you start by connecting a lambda to the signal so that you know that it's being emitted?

      L Offline
      L Offline
      leinad
      wrote on last edited by
      #3

      @JonB Sorry. I fixed using the back tics. Can you explain how I can connect a lambda to the signal?

      Atr0p0sA JonBJ 2 Replies Last reply
      0
      • L leinad

        @JonB Sorry. I fixed using the back tics. Can you explain how I can connect a lambda to the signal?

        Atr0p0sA Offline
        Atr0p0sA Offline
        Atr0p0s
        wrote on last edited by
        #4

        @leinad Here is a good explanation.

        1 Reply Last reply
        0
        • L leinad

          @JonB Sorry. I fixed using the back tics. Can you explain how I can connect a lambda to the signal?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #5

          @leinad
          That's much more readable, thank you :)

          I didn't want to bring this up, because it likely has nothing to do with your issue, but SIGNAL/SLOT() macros are the old style of Qt connect()s. Unfortunately a lot of examples on the web still use them. The new style was introduced a decade ago as C++ supported it. It is type-safe and gives compile time errors if the slot is not right for the signal.

          connect(signalObject, &SignalClass::method, slotObject, &SlotClass::method);
          

          So for your connect(selectdatabase_, SIGNAL(sendDatabaseName(QString)), databaseProcessing_, SLOT(getDatabaseName(QString)));:

          connect(selectdatabase_, &SelectDatabase::sendDatabaseName, databaseProcessing_, &DatabaseProcessing::getDatabaseName);
          

          Doesn't that look tidier? :) I really suggest you change to this syntax from now onwards.

          You need new-style to use C++ lambdas for the slot. I suggest you try something like:

          connect(selectdatabase_, &SelectDatabase::sendDatabaseName,
                  databaseProcessing_, [](QString databaseName) { qDebug() << "sendDatabaseName" << databaseName; } );
          

          Now we know whether signal is emitted and passes database name. Does this work?

          L 2 Replies Last reply
          0
          • JonBJ JonB

            @leinad
            That's much more readable, thank you :)

            I didn't want to bring this up, because it likely has nothing to do with your issue, but SIGNAL/SLOT() macros are the old style of Qt connect()s. Unfortunately a lot of examples on the web still use them. The new style was introduced a decade ago as C++ supported it. It is type-safe and gives compile time errors if the slot is not right for the signal.

            connect(signalObject, &SignalClass::method, slotObject, &SlotClass::method);
            

            So for your connect(selectdatabase_, SIGNAL(sendDatabaseName(QString)), databaseProcessing_, SLOT(getDatabaseName(QString)));:

            connect(selectdatabase_, &SelectDatabase::sendDatabaseName, databaseProcessing_, &DatabaseProcessing::getDatabaseName);
            

            Doesn't that look tidier? :) I really suggest you change to this syntax from now onwards.

            You need new-style to use C++ lambdas for the slot. I suggest you try something like:

            connect(selectdatabase_, &SelectDatabase::sendDatabaseName,
                    databaseProcessing_, [](QString databaseName) { qDebug() << "sendDatabaseName" << databaseName; } );
            

            Now we know whether signal is emitted and passes database name. Does this work?

            L Offline
            L Offline
            leinad
            wrote on last edited by
            #6

            @JonB
            Thanks, I see. I will give it a try.

            1 Reply Last reply
            0
            • JonBJ JonB

              @leinad
              That's much more readable, thank you :)

              I didn't want to bring this up, because it likely has nothing to do with your issue, but SIGNAL/SLOT() macros are the old style of Qt connect()s. Unfortunately a lot of examples on the web still use them. The new style was introduced a decade ago as C++ supported it. It is type-safe and gives compile time errors if the slot is not right for the signal.

              connect(signalObject, &SignalClass::method, slotObject, &SlotClass::method);
              

              So for your connect(selectdatabase_, SIGNAL(sendDatabaseName(QString)), databaseProcessing_, SLOT(getDatabaseName(QString)));:

              connect(selectdatabase_, &SelectDatabase::sendDatabaseName, databaseProcessing_, &DatabaseProcessing::getDatabaseName);
              

              Doesn't that look tidier? :) I really suggest you change to this syntax from now onwards.

              You need new-style to use C++ lambdas for the slot. I suggest you try something like:

              connect(selectdatabase_, &SelectDatabase::sendDatabaseName,
                      databaseProcessing_, [](QString databaseName) { qDebug() << "sendDatabaseName" << databaseName; } );
              

              Now we know whether signal is emitted and passes database name. Does this work?

              L Offline
              L Offline
              leinad
              wrote on last edited by
              #7

              @JonB said in Weird issue with SIGNAL/SLOT:

              connect(signalObject, &SignalClass::method, slotObject, &SlotClass::method);

              Funny, I use QtCreator with TIDY and it never called it out as a bad style. Perhaps the default options disable it?

              L 1 Reply Last reply
              0
              • L leinad

                @JonB said in Weird issue with SIGNAL/SLOT:

                connect(signalObject, &SignalClass::method, slotObject, &SlotClass::method);

                Funny, I use QtCreator with TIDY and it never called it out as a bad style. Perhaps the default options disable it?

                L Offline
                L Offline
                leinad
                wrote on last edited by
                #8

                @JonB

                connect(selectdatabase_, &SelectDatabase::sendDatabaseName,
                        databaseProcessing_, [](QString databaseName) { qDebug() << "sendDatabaseName" << databaseName; } );
                

                I'm afraid I can't use this lambda function because I don't have access to databaseName, it is a QString which is sent from another object outside of the connect class.

                L 1 Reply Last reply
                0
                • L leinad

                  @JonB

                  connect(selectdatabase_, &SelectDatabase::sendDatabaseName,
                          databaseProcessing_, [](QString databaseName) { qDebug() << "sendDatabaseName" << databaseName; } );
                  

                  I'm afraid I can't use this lambda function because I don't have access to databaseName, it is a QString which is sent from another object outside of the connect class.

                  L Offline
                  L Offline
                  leinad
                  wrote on last edited by
                  #9

                  @JonB
                  Sorry never mind. I can indeed use it.

                  L 1 Reply Last reply
                  0
                  • L leinad

                    @JonB
                    Sorry never mind. I can indeed use it.

                    L Offline
                    L Offline
                    leinad
                    wrote on last edited by
                    #10

                    @leinad
                    So it appears that the lambda does indeed show the correct value passed but yet the SLOT does not show it :(

                    JonBJ 1 Reply Last reply
                    0
                    • L leinad

                      @leinad
                      So it appears that the lambda does indeed show the correct value passed but yet the SLOT does not show it :(

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #11

                      @leinad
                      This was just the first step. Now we know the signal does get emitted and the connect() attaches to it.

                      Now:

                      connect(selectdatabase_, &SelectDatabase::sendDatabaseName, databaseProcessing_, &DatabaseProcessing::getDatabaseName)
                      

                      (Put a qDebug() << databaseName; as first statement in slot.) I presume you will say the slot does not get called?

                      If not, are selectdatabase_ and databaseProcessing_ in different threads? If so, do you allow the event loop to run (signals across threads are queued)?

                      L 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @leinad
                        This was just the first step. Now we know the signal does get emitted and the connect() attaches to it.

                        Now:

                        connect(selectdatabase_, &SelectDatabase::sendDatabaseName, databaseProcessing_, &DatabaseProcessing::getDatabaseName)
                        

                        (Put a qDebug() << databaseName; as first statement in slot.) I presume you will say the slot does not get called?

                        If not, are selectdatabase_ and databaseProcessing_ in different threads? If so, do you allow the event loop to run (signals across threads are queued)?

                        L Offline
                        L Offline
                        leinad
                        wrote on last edited by
                        #12

                        @JonB
                        I figured out what is happening. Seems the Emit is being called before the connect statement had a chance to be called. I'll have to rearrange how statements get executed.

                        Thanks!

                        1 Reply Last reply
                        0
                        • L leinad has marked this topic as solved on

                        • Login

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