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. Question about connect() function with the SIGNAL and SLOT macros
Forum Updated to NodeBB v4.3 + New Features

Question about connect() function with the SIGNAL and SLOT macros

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 4 Posters 790 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.
  • S Offline
    S Offline
    szmf
    wrote on last edited by
    #1

    I have some questions about how the connect() function with the SIGNAL and SLOT macros locates the signals and slots. Here is my code:

    Interface.h defines two classes, ClassA for providing an interface and ClassB for inheriting from QObject.

    #pragma once
    #include <QObject>
    
    class ClassA
    {
    public:
        virtual void test() = 0;
        virtual void emitSignal() = 0;
    };
    
    class ClassB: public QObject
    {};
    

    Entity.h defines the multiple inheritance class Entity and declares a signal and a slot.

    class Entity: public ClassB, public ClassA
    {
        Q_OBJECT
    
    public:
        Entity() = default;
    
        virtual void test() override { qDebug() << "virtual function"; }
        virtual void emitSignal() override { emit sig_e(); }
    
        void test1() { qDebug() << "member function"; }
    
    signals:
        void sig_e();
    
    public slots:
        void slot_e() { qDebug() << "slot triggered"; }
    };
    

    Creator.h defines the Creator class for generating Entity objects.

    #pragma once
    #include "Interface.h"
    
    class Creator
    {
    public:
        Creator() = default;
        ClassA* CreateEntity();
    };
    

    In Creator.cpp, Entity.h is included to ensure that Entity is not visible to users of Creator.

    #include "Creator.h"
    #include "Entity.h"
    
    ClassA* Creator::CreateEntity()
    {
        ClassA* e = new Entity;
        return e;
    }
    

    In the main file, I include Interface.h and Creator.h. The code and the running result are as follows:

    #include "Interface.h"
    #include "Creator.h"
    
    #include <QtCore>
    #include <QObject>
    
    int main(int argc, char *argv[])
    {
    
        Creator c;
        ClassA* ca = c.CreateEntity();
        ca->test();
        //ca->test1();    //No member named 'test1' in 'ClassA'
    
        qDebug() << "----- 1 -----";
        ca->emitSignal();
    
        ClassB* cb = dynamic_cast<ClassB*>(ca);	
        QObject::connect(cb, SIGNAL(sig_e()), cb, SLOT(slot_e()));	// why does this work?
    //    QObject::connect(cb, &ClassA::sig_e, cb, &ClassA::slot_e);  //No member named 'sig_e' in 'ClassA'
    //    QObject::connect(cb, &ClassB::sig_e, cb, &ClassB::slot_e);  //No member named 'sig_e' in 'ClassB'
    //    QObject::connect(cb, &Entity::sig_e, cb, &Entity::slot_e);  //Use of undeclared identifier 'Entity'
    
        qDebug() << "----- 2 -----";
        ca->emitSignal();
    
        return 0;
    }
    
    virtual function
    ----- 1 -----
    ----- 2 -----
    slot triggered
    

    Why does the connect() function with the SIGNAL and SLOT macros accurately locate and connect the signals and slots of the Entity class?

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

      Hi, when you're using the SIGNAL and SLOT macros all the locating and connecting are done when you start the program (not when you compile it).
      When you're using connect() without those macros, the locating of the classes are done when you compile the program.

      So for the 2nd case (but not the 1st) the compiler needs to see all the classes involved.

      S 1 Reply Last reply
      2
      • hskoglundH hskoglund

        Hi, when you're using the SIGNAL and SLOT macros all the locating and connecting are done when you start the program (not when you compile it).
        When you're using connect() without those macros, the locating of the classes are done when you compile the program.

        So for the 2nd case (but not the 1st) the compiler needs to see all the classes involved.

        S Offline
        S Offline
        szmf
        wrote on last edited by
        #3

        @hskoglund Thank you for your response. I think I have a general understanding of the reason.
        The SIGNAL and SLOT macros in essence are strings. The code snippet QObject::connect(cb, SIGNAL(sig_e()), cb, SLOT(slot_e())); is equivalent to QObject::connect(cb, "2sig_e()", cb, "1slot_e()");. By using these macros, the code bypasses the compiler's type checking. This is why the code can compile successfully.
        The process of searching for signals and slots and establishing connections is handled by the meta-object system.

        JonBJ Pl45m4P 2 Replies Last reply
        0
        • S szmf has marked this topic as solved on
        • S szmf

          @hskoglund Thank you for your response. I think I have a general understanding of the reason.
          The SIGNAL and SLOT macros in essence are strings. The code snippet QObject::connect(cb, SIGNAL(sig_e()), cb, SLOT(slot_e())); is equivalent to QObject::connect(cb, "2sig_e()", cb, "1slot_e()");. By using these macros, the code bypasses the compiler's type checking. This is why the code can compile successfully.
          The process of searching for signals and slots and establishing connections is handled by the meta-object system.

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #4

          @szmf
          You are correct. As you say, the macros lose type checking, at least at compile time. Unless you have a particular usage reason, may I suggest you always use the new syntax rather than the string macros.

          1 Reply Last reply
          2
          • S szmf

            @hskoglund Thank you for your response. I think I have a general understanding of the reason.
            The SIGNAL and SLOT macros in essence are strings. The code snippet QObject::connect(cb, SIGNAL(sig_e()), cb, SLOT(slot_e())); is equivalent to QObject::connect(cb, "2sig_e()", cb, "1slot_e()");. By using these macros, the code bypasses the compiler's type checking. This is why the code can compile successfully.
            The process of searching for signals and slots and establishing connections is handled by the meta-object system.

            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by
            #5

            @szmf

            To add:

            One more situation where you could face different behavior is when you are dealing with parent inside a QObject.
            Let's say your QObject has a fixed parent, which never changes (important) during its lifetime.
            Assume a signal foo() that is connected to a slot called bar() in your parent class.

            This works (besides it's not recommended or a good practise to do so):

            connect(this, SIGNAL(foo()), parent(), SLOT(bar());
            

            while none of these work, for the same reason mentioned above:

            connect(this, &MyClass::foo, parent(), &ParentClass::bar);
            connect(this, &MyClass::foo, parent(), &QObject::bar);
            connect(this, &MyClass::foo, parentWidget(), &QWidget::bar);
            

            During compilation parent is not definite, therefore you would get an error that slot bar() can't be resolved / was not found.
            Whereas the first example works, as the check is performed at runtime where parent() is already linked to your actual parent class, which should hold a slot called bar().


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            1 Reply Last reply
            1

            • Login

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