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. Connecting to signal of another class
QtWS25 Last Chance

Connecting to signal of another class

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 6 Posters 949 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.
  • K Offline
    K Offline
    kengineer
    wrote on last edited by kengineer
    #1

    Hello, I am attempting to connect a signal from one class instance to another but am having trouble.

    Here is the scenario. I have 3 classes, ClassA, ClassB and ClassC. ClassA inherits ClassB, ClassB inherits QObject, and ClassC inherits QObject.

    The idea is that I will create potentially multiple instances of ClassA, whose inherited class B instance needs to receive signals from the same single instance of ClassC. ClassA registers a pointer to the ClassC instance upon creation, and ClassB will use that to connect to the signal.

    However, this method is crashing upon invoking connect in the constructor of Class B. I get a seg fault, which is probably because of some type of null pointer, but I can't tell exactly. See code below:

    // classa.cpp
    #include <classa.h>
    
    ClassA::ClassA(ClassC * somecclass)
    {
        classc = somecclass;
    }
    
    
    // classa.h
    #ifndef CLASSA_H
    #define CLASSA_H
    
    #include <classb.h>
    #include <classc.h>
    #include <QObject>
    
    class ClassA: ClassB
    {
        Q_OBJECT
    public:
        ClassA(ClassC * somecclass);
    };
    
    #endif // CLASSA_H
    
    
    // classb.cpp
    #include "classb.h"
    
    ClassB::ClassB()
    {
        // Crash happens here
        connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
    }
    
    void ClassB::classBslot(void)
    {
    
    }
    
    
    // classb.h
    
    #ifndef CLASSB_H
    #define CLASSB_H
    
    #include <QObject>
    #include <classc.h>
    
    class ClassB : public QObject
    {
        Q_OBJECT
    public:
        ClassB();
        ClassC * classc;
    
    signals:
    public slots:
        void classBslot(void);
    };
    
    #endif // CLASSB_H
    
    
    // classc.cpp
    #include "classc.h"
    
    ClassC::ClassC()
    {
    
    }
    
    
    // classc.h
    #ifndef CLASSC_H
    #define CLASSC_H
    
    #include <QObject>
    
    class ClassC : public QObject
    {
        Q_OBJECT
    public:
        ClassC();
    
    signals:
        void classCsignal();
    public slots:
    };
    
    
    #endif // CLASSC_H
    
    // main.cpp
    
    ClassC classc;
    ClassA classa(&classc);
    
    // loop and do other stuff
        
    
    

    If however in ClassB, instead of having a pointer, I create a local instance of ClassC and then use this in connect, it works. Why can't I do the original way? Is there some weird order of QObject initialization where the signals aren't there yet or something, or am I missing something else? I'm simply use a pointer to an outside already initialize outside instance of a class vs. a local instance.

    Thanks

    Pablo J. RoginaP 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Looks like your classC object is not initialised before you use it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      2
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #3

        Hi
        That should work fine as longs ClassC classc; stays in scope.
        So i would check my cached pointer

        in .h
        ClassC * classc=nullptr;

        and

        ClassB::ClassB() // it has no parameter here of type ClassC ???? so where do you store it ?
        {
        // Crash happens here
        if (!classc )
        qDebug() << "ptr is null";
        else
        connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
        }

        K 1 Reply Last reply
        0
        • mrjjM mrjj

          Hi
          That should work fine as longs ClassC classc; stays in scope.
          So i would check my cached pointer

          in .h
          ClassC * classc=nullptr;

          and

          ClassB::ClassB() // it has no parameter here of type ClassC ???? so where do you store it ?
          {
          // Crash happens here
          if (!classc )
          qDebug() << "ptr is null";
          else
          connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
          }

          K Offline
          K Offline
          kengineer
          wrote on last edited by kengineer
          #4

          @SGaist said in Connecting to signal of another class:

          Hi,

          Looks like your classC object is not initialised before you use it.

          What do you mean? I create an instance of it in main before creating a ClassB instance.

          @mrjj said in Connecting to signal of another class:

          Hi
          That should work fine as longs ClassC classc; stays in scope.
          So i would check my cached pointer

          in .h
          ClassC * classc=nullptr;

          and

          ClassB::ClassB() // it has no parameter here of type ClassC ???? so where do you store it ?
          {
          // Crash happens here
          if (!classc )
          qDebug() << "ptr is null";
          else
          connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
          }

          I verified that classc is not a NULL pointer.

          The ClassC pointer is indeed stored in the ClassB instance:

          // classb.h
          public:
              ClassB();
              ClassC * classc;
          

          This should not go out of scope because main never returns. Also, I verified that if I do this same exact method, but instead call connect in a separate function call, it works fine. It seems that this just doesn't work when called from the constructor.

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            So
            the real code looks like
            ClassB(ClassC *theptr) : classc(theptr ) {

            connect(classc, xxxx )
            }

            ?

            K 1 Reply Last reply
            0
            • mrjjM mrjj

              So
              the real code looks like
              ClassB(ClassC *theptr) : classc(theptr ) {

              connect(classc, xxxx )
              }

              ?

              K Offline
              K Offline
              kengineer
              wrote on last edited by
              #6

              @mrjj said in Connecting to signal of another class:

              So
              the real code looks like
              ClassB(ClassC *theptr) : classc(theptr ) {

              connect(classc, xxxx )
              }

              ?

              No ClassB doesn't inherit ClassC. There's simply a static ClassC * pointer called "classc" in ClassB. This holds a reference to an instance of ClassC .

              The reason for doing it this way, is there will be a single instance of ClassC, which ClassA/(and inherited ClassB) need to all reference.

              i.e.

              ClassC globalCinstance;
              
              ClassA classAinstance1(&globalCinstance);
              ClassA classAinstance2(&globalCinstance);
              ClassA classAinstance3(&globalCinstance);
              

              What I was saying that does work, is doing something like this:

              // main.cpp
              ClassC someclassC;
              ClassA someclassA;
              someclassA.registerSignal();
              

              where

              // classb.cpp
              void ClassB::registerSignal()
              {
              connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
              }
              

              and even this works too:

              // main.cpp
              ClassC someclassC;
              ClassA someclassA;
              
              // classa.cpp
              ClassA::ClassA(ClassC * somecclass)
              {
                  classc = somecclass;
              
                 // Call registerSignal from inherited ClassB
                 registerSignal();
              }
              
              // classb.cpp
              void ClassB::registerSignal()
              {
              connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
              }
              
              

              It seems that it just can't be called from the constructor of ClassB

              mranger90M 1 Reply Last reply
              0
              • K kengineer

                Hello, I am attempting to connect a signal from one class instance to another but am having trouble.

                Here is the scenario. I have 3 classes, ClassA, ClassB and ClassC. ClassA inherits ClassB, ClassB inherits QObject, and ClassC inherits QObject.

                The idea is that I will create potentially multiple instances of ClassA, whose inherited class B instance needs to receive signals from the same single instance of ClassC. ClassA registers a pointer to the ClassC instance upon creation, and ClassB will use that to connect to the signal.

                However, this method is crashing upon invoking connect in the constructor of Class B. I get a seg fault, which is probably because of some type of null pointer, but I can't tell exactly. See code below:

                // classa.cpp
                #include <classa.h>
                
                ClassA::ClassA(ClassC * somecclass)
                {
                    classc = somecclass;
                }
                
                
                // classa.h
                #ifndef CLASSA_H
                #define CLASSA_H
                
                #include <classb.h>
                #include <classc.h>
                #include <QObject>
                
                class ClassA: ClassB
                {
                    Q_OBJECT
                public:
                    ClassA(ClassC * somecclass);
                };
                
                #endif // CLASSA_H
                
                
                // classb.cpp
                #include "classb.h"
                
                ClassB::ClassB()
                {
                    // Crash happens here
                    connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
                }
                
                void ClassB::classBslot(void)
                {
                
                }
                
                
                // classb.h
                
                #ifndef CLASSB_H
                #define CLASSB_H
                
                #include <QObject>
                #include <classc.h>
                
                class ClassB : public QObject
                {
                    Q_OBJECT
                public:
                    ClassB();
                    ClassC * classc;
                
                signals:
                public slots:
                    void classBslot(void);
                };
                
                #endif // CLASSB_H
                
                
                // classc.cpp
                #include "classc.h"
                
                ClassC::ClassC()
                {
                
                }
                
                
                // classc.h
                #ifndef CLASSC_H
                #define CLASSC_H
                
                #include <QObject>
                
                class ClassC : public QObject
                {
                    Q_OBJECT
                public:
                    ClassC();
                
                signals:
                    void classCsignal();
                public slots:
                };
                
                
                #endif // CLASSC_H
                
                // main.cpp
                
                ClassC classc;
                ClassA classa(&classc);
                
                // loop and do other stuff
                    
                
                

                If however in ClassB, instead of having a pointer, I create a local instance of ClassC and then use this in connect, it works. Why can't I do the original way? Is there some weird order of QObject initialization where the signals aren't there yet or something, or am I missing something else? I'm simply use a pointer to an outside already initialize outside instance of a class vs. a local instance.

                Thanks

                Pablo J. RoginaP Offline
                Pablo J. RoginaP Offline
                Pablo J. Rogina
                wrote on last edited by
                #7

                @kengineer said in Connecting to signal of another class:

                connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));

                You may want to use signals and slots new syntax as it provides information at compile time which may shed some light about your issue

                Upvote the answer(s) that helped you solve the issue
                Use "Topic Tools" button to mark your post as Solved
                Add screenshots via postimage.org
                Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                1
                • K kengineer

                  @mrjj said in Connecting to signal of another class:

                  So
                  the real code looks like
                  ClassB(ClassC *theptr) : classc(theptr ) {

                  connect(classc, xxxx )
                  }

                  ?

                  No ClassB doesn't inherit ClassC. There's simply a static ClassC * pointer called "classc" in ClassB. This holds a reference to an instance of ClassC .

                  The reason for doing it this way, is there will be a single instance of ClassC, which ClassA/(and inherited ClassB) need to all reference.

                  i.e.

                  ClassC globalCinstance;
                  
                  ClassA classAinstance1(&globalCinstance);
                  ClassA classAinstance2(&globalCinstance);
                  ClassA classAinstance3(&globalCinstance);
                  

                  What I was saying that does work, is doing something like this:

                  // main.cpp
                  ClassC someclassC;
                  ClassA someclassA;
                  someclassA.registerSignal();
                  

                  where

                  // classb.cpp
                  void ClassB::registerSignal()
                  {
                  connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
                  }
                  

                  and even this works too:

                  // main.cpp
                  ClassC someclassC;
                  ClassA someclassA;
                  
                  // classa.cpp
                  ClassA::ClassA(ClassC * somecclass)
                  {
                      classc = somecclass;
                  
                     // Call registerSignal from inherited ClassB
                     registerSignal();
                  }
                  
                  // classb.cpp
                  void ClassB::registerSignal()
                  {
                  connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
                  }
                  
                  

                  It seems that it just can't be called from the constructor of ClassB

                  mranger90M Offline
                  mranger90M Offline
                  mranger90
                  wrote on last edited by
                  #8

                  @kengineer
                  That's because A INHERITS from B. That means that B is being constructed before A and at that point the classC member variable has not been assigned a value.

                  kshegunovK K 2 Replies Last reply
                  7
                  • mranger90M mranger90

                    @kengineer
                    That's because A INHERITS from B. That means that B is being constructed before A and at that point the classC member variable has not been assigned a value.

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

                    Well spotted!

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    0
                    • mranger90M mranger90

                      @kengineer
                      That's because A INHERITS from B. That means that B is being constructed before A and at that point the classC member variable has not been assigned a value.

                      K Offline
                      K Offline
                      kengineer
                      wrote on last edited by
                      #10

                      @mranger90 thanks yes that would be an issue wouldn't it. I'm a C programmer that's rather new to C++, I was actually reading about construction order but had it mixed around in my head. This makes sense, thanks!

                      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