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. Signal/Slot connection not working when connected in constructor
Forum Updated to NodeBB v4.3 + New Features

Signal/Slot connection not working when connected in constructor

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 2.2k Views 1 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.
  • R Offline
    R Offline
    rprueckl
    wrote on 6 Apr 2020, 11:26 last edited by
    #1

    Hi,

    I want to connect some signals to some slots in an application of mine. In this very situation, this does NOT work when the connection is established in the constructor, but is DOES work when it is done somewhere later in the program logic (e.g. in a slot called after a button click).

    I explain the situation with some example code:

    I have a dll that declares a Qt plugin (class MyObject) that inherits from MySignalInterface.
    MyObject owns MySubObject, that inherits from MySlotInterface.
    Compiling/building/loading the plugin all works fine. When I now want to connect the mySignal from MyObject to mySlot from MySubObject in the constructor of MyObject, the slot is not called when the signal is emitted (I checked that the signal is emitted by setting a breakpoint in the respective moc_MyObject.cpp). When I connect somewhere later (within onButtonPress()), the connection works. There is no output on the command line regarding failed signal/slot connections, and the result value from the call to connect() in the constructor is true.
    I don't know how to investigate what is going wrong here with the connections. How to debug this?

    Below, some code fragments for clarification. Any help would be appreciated.
    I am working on Windows10 with Visual Studio 2015 and Qt 5.10.0.

    MyObject.cpp

    MyObject::MyObject()
      : mySubObject(new MySubObject())
    {
      connectSignals(); // connection does not work; slot is not called when signal is emitted
    }
    
    void MyObject::connectSignals()
    {
      connect(this, &MyObject::mySignal, mySubObject, &MySubObject::mySlot);
    }
    
    void MyObject::onButtonPress() // called i.e. in response to a button press
    {
      connectSignals(); // connection works, slot is called when signal is emitted
    }
    

    MyObject.h

    class MYOBJECTMODULE_EXPORT MyObject final :
      public QObject,
      public MySignalInterface
    {
      Q_OBJECT
      Q_PLUGIN_METADATA(IID "MyObject" FILE "myobject.json")
      Q_INTERFACES(MySignalInterface)
    
    public:
      MyObject();
    
    signals:
      void mySignal() override; // from MySignalInterface
    
    public slots:
      void onButtonPress();
    
    private:
      MySubObject* mySubObject;
      
      void connectSignals();
    };
    

    MySignalInterface.h

    class MySignalInterface
    {
    public:
        // signals:
        virtual void mySignal() = 0;
    };
    
    QT_BEGIN_NAMESPACE
    #define MySignalInterface_iid "MySignalInterface/1.0"
    Q_DECLARE_INTERFACE(MySignalInterface, MySignalInterface_iid)
    QT_END_NAMESPACE
    

    MySubObject.h

    class MySubObject :
      public QMainWindow,
      public MySlotInterface
    {
      Q_OBJECT
    
    public:
      MySubObject(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags());
    
    public slots:
      virtual void mySlot() override;
          
    };
    

    MySlotInterface.h

    class MySlotInterface
    {
    public:
        // public slots:
        virtual void mySlot() = 0;
    };
    
    QT_BEGIN_NAMESPACE
    #define MySlotInterface_iid "MySlotInterface/1.0"
    Q_DECLARE_INTERFACE(MySlotInterface, MySlotInterface_iid)
    QT_END_NAMESPACE
    
    J 1 Reply Last reply 6 Apr 2020, 11:32
    0
    • R Offline
      R Offline
      rprueckl
      wrote on 27 Apr 2020, 16:01 last edited by
      #10

      After a long investigation the embarrassing truth: I called disconnect() at a place in my code without clearly considering which signals are actually disconnected here.

      Just a short explanation: I have a top-level application that loads plugins, with each plugin having a main class. The top-level application connects the signals of the main classes of the plugins together to form a pipeline. Whenever the pipeline is updated, the previous connections between the modules have to be cleared before being connected again. For this purpose I called disconnect() for every top-level class of the loaded modules. What I didn't bear in mind was that this call also disconnected the signals of a main module directed to their sub-modules.

      Thank you anyway for your support!

      1 Reply Last reply
      0
      • R rprueckl
        6 Apr 2020, 11:26

        Hi,

        I want to connect some signals to some slots in an application of mine. In this very situation, this does NOT work when the connection is established in the constructor, but is DOES work when it is done somewhere later in the program logic (e.g. in a slot called after a button click).

        I explain the situation with some example code:

        I have a dll that declares a Qt plugin (class MyObject) that inherits from MySignalInterface.
        MyObject owns MySubObject, that inherits from MySlotInterface.
        Compiling/building/loading the plugin all works fine. When I now want to connect the mySignal from MyObject to mySlot from MySubObject in the constructor of MyObject, the slot is not called when the signal is emitted (I checked that the signal is emitted by setting a breakpoint in the respective moc_MyObject.cpp). When I connect somewhere later (within onButtonPress()), the connection works. There is no output on the command line regarding failed signal/slot connections, and the result value from the call to connect() in the constructor is true.
        I don't know how to investigate what is going wrong here with the connections. How to debug this?

        Below, some code fragments for clarification. Any help would be appreciated.
        I am working on Windows10 with Visual Studio 2015 and Qt 5.10.0.

        MyObject.cpp

        MyObject::MyObject()
          : mySubObject(new MySubObject())
        {
          connectSignals(); // connection does not work; slot is not called when signal is emitted
        }
        
        void MyObject::connectSignals()
        {
          connect(this, &MyObject::mySignal, mySubObject, &MySubObject::mySlot);
        }
        
        void MyObject::onButtonPress() // called i.e. in response to a button press
        {
          connectSignals(); // connection works, slot is called when signal is emitted
        }
        

        MyObject.h

        class MYOBJECTMODULE_EXPORT MyObject final :
          public QObject,
          public MySignalInterface
        {
          Q_OBJECT
          Q_PLUGIN_METADATA(IID "MyObject" FILE "myobject.json")
          Q_INTERFACES(MySignalInterface)
        
        public:
          MyObject();
        
        signals:
          void mySignal() override; // from MySignalInterface
        
        public slots:
          void onButtonPress();
        
        private:
          MySubObject* mySubObject;
          
          void connectSignals();
        };
        

        MySignalInterface.h

        class MySignalInterface
        {
        public:
            // signals:
            virtual void mySignal() = 0;
        };
        
        QT_BEGIN_NAMESPACE
        #define MySignalInterface_iid "MySignalInterface/1.0"
        Q_DECLARE_INTERFACE(MySignalInterface, MySignalInterface_iid)
        QT_END_NAMESPACE
        

        MySubObject.h

        class MySubObject :
          public QMainWindow,
          public MySlotInterface
        {
          Q_OBJECT
        
        public:
          MySubObject(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags());
        
        public slots:
          virtual void mySlot() override;
              
        };
        

        MySlotInterface.h

        class MySlotInterface
        {
        public:
            // public slots:
            virtual void mySlot() = 0;
        };
        
        QT_BEGIN_NAMESPACE
        #define MySlotInterface_iid "MySlotInterface/1.0"
        Q_DECLARE_INTERFACE(MySlotInterface, MySlotInterface_iid)
        QT_END_NAMESPACE
        
        J Offline
        J Offline
        J.Hilk
        Moderators
        wrote on 6 Apr 2020, 11:32 last edited by
        #2

        @rprueckl said in Signal/Slot connection not working when connected in constructor:

        mySubObject

        you probably new(instantiate) mySubObject() after the connect call.


        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.

        R 1 Reply Last reply 6 Apr 2020, 11:46
        1
        • J J.Hilk
          6 Apr 2020, 11:32

          @rprueckl said in Signal/Slot connection not working when connected in constructor:

          mySubObject

          you probably new(instantiate) mySubObject() after the connect call.

          R Offline
          R Offline
          rprueckl
          wrote on 6 Apr 2020, 11:46 last edited by
          #3

          Hi @J-Hilk ,
          thanks for the quick input. I just checked (by setting a breakpoint in the constructor of MySubObject) - it is only called once.

          J 1 Reply Last reply 6 Apr 2020, 11:49
          0
          • R rprueckl
            6 Apr 2020, 11:46

            Hi @J-Hilk ,
            thanks for the quick input. I just checked (by setting a breakpoint in the constructor of MySubObject) - it is only called once.

            J Offline
            J Offline
            J.Hilk
            Moderators
            wrote on 6 Apr 2020, 11:49 last edited by
            #4

            @rprueckl said in Signal/Slot connection not working when connected in constructor:

            thanks for the quick input. I just checked (by setting a breakpoint in the constructor of MySubObject) - it is only called once.

            and what would that tell you ?

            You can't even definitely say, if the object is initialized or not, because you don't assign the member pointer to null (initially)

            MySubObject* mySubObject;
            

            So even when debugging you may see something != 0, but the object is still not initialized.


            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.

            R 1 Reply Last reply 6 Apr 2020, 12:16
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on 6 Apr 2020, 11:54 last edited by
              #5

              Hi,

              Where exactly are you emitting that signal ?

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

              R 1 Reply Last reply 6 Apr 2020, 12:20
              0
              • J J.Hilk
                6 Apr 2020, 11:49

                @rprueckl said in Signal/Slot connection not working when connected in constructor:

                thanks for the quick input. I just checked (by setting a breakpoint in the constructor of MySubObject) - it is only called once.

                and what would that tell you ?

                You can't even definitely say, if the object is initialized or not, because you don't assign the member pointer to null (initially)

                MySubObject* mySubObject;
                

                So even when debugging you may see something != 0, but the object is still not initialized.

                R Offline
                R Offline
                rprueckl
                wrote on 6 Apr 2020, 12:16 last edited by
                #6

                @J-Hilk

                The breakpoint in the constructor of mySubObject is hit because mySubObject is created in the member initialization list of MyObject.

                MyObject::MyObject()
                  : mySubObject(new MySubObject())
                

                which is before the call to connect. After this, the constructor of mySubObject is not called anymore, which tells me that there is no second object constructed anywhere.
                As I don't encounter a std::bad_alloc exception, I assume the object is correctly created.

                J 1 Reply Last reply 6 Apr 2020, 12:19
                1
                • R rprueckl
                  6 Apr 2020, 12:16

                  @J-Hilk

                  The breakpoint in the constructor of mySubObject is hit because mySubObject is created in the member initialization list of MyObject.

                  MyObject::MyObject()
                    : mySubObject(new MySubObject())
                  

                  which is before the call to connect. After this, the constructor of mySubObject is not called anymore, which tells me that there is no second object constructed anywhere.
                  As I don't encounter a std::bad_alloc exception, I assume the object is correctly created.

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 6 Apr 2020, 12:19 last edited by
                  #7

                  @rprueckl thanks for the clarification I missed the initalizerlist due to the linebreak 🙈


                  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.

                  1 Reply Last reply
                  0
                  • SGaistS SGaist
                    6 Apr 2020, 11:54

                    Hi,

                    Where exactly are you emitting that signal ?

                    R Offline
                    R Offline
                    rprueckl
                    wrote on 6 Apr 2020, 12:20 last edited by
                    #8

                    @SGaist
                    The origin of the signal is in another plugin, which implements a counterpart of the interface of the plugin in question. The signals of the two plugins are connected in the host application, which loads the plugins.
                    So it is:

                    Plugin2(dll2) mySignal() --> myObject(dll1) mySignal() --> mySubObject(dll1) mySlot()

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 6 Apr 2020, 18:12 last edited by
                      #9

                      Can you provide a minimal compilable project that shows that issue ?

                      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
                      0
                      • R Offline
                        R Offline
                        rprueckl
                        wrote on 27 Apr 2020, 16:01 last edited by
                        #10

                        After a long investigation the embarrassing truth: I called disconnect() at a place in my code without clearly considering which signals are actually disconnected here.

                        Just a short explanation: I have a top-level application that loads plugins, with each plugin having a main class. The top-level application connects the signals of the main classes of the plugins together to form a pipeline. Whenever the pipeline is updated, the previous connections between the modules have to be cleared before being connected again. For this purpose I called disconnect() for every top-level class of the loaded modules. What I didn't bear in mind was that this call also disconnected the signals of a main module directed to their sub-modules.

                        Thank you anyway for your support!

                        1 Reply Last reply
                        0

                        • Login

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