SIGNAL & SLOT macros in Qt : what do they do?
Asked Answered
S

4

13

I'm a beginner in Qt and trying to understand the SIGNAL and SLOT macros. When I'm learning to use the connect method to bind the signal and slot, I found the tutorials on Qt's official reference page uses:

connect(obj1, SIGNAL(signal(int)), obj2, SLOT(slot()))

However, this also works very well:

connect(obj1, &Obj1::signal, obj2, &Obj2::slot)

So what exactly do the macros SIGNAL and SLOT do? Do they just look for the signal in the class the object belongs to and return the address of it?

Then why do most programmers use these macros instead of using &Obj1::signal since the latter appears to be simpler and you don't need to change the code if the parameters of the signal function change?

Sheldon answered 23/7, 2015 at 13:52 Comment(0)
A
11

The use of the SIGNAL and SLOT macros used to be the only way to make connections, before Qt 5. The connection is made at runtime and require signal and slots to be marked in the header. For example:

Class MyClass : public QObject
{
    Q_OBJECT
    signals:
        void Signal();

    slots:
        void ASlotFunction();
};

To avoid repetition, the way in which it works is described in the QT 4 documentation.

The signal and slot mechanism is part of the C++ extensions that are provided by Qt and make use of the Meta Object Compiler (moc).

This explains why signals and slots use the moc.

The second connect method is much improved as the functions specified can be checked at the time of compilation, not runtime. In addition, by using the address of a function, you can refer to any class function, not just those in the section marked slots:

The documentation was updated for Qt 5.

In addition, there's a good blog post about the Qt 4 connect workings here and Qt 5 here.

Asset answered 23/7, 2015 at 14:0 Comment(0)
B
7

Addition to the first answer.

what exactly did the macro SIGNAL and SLOT do

Almost nothing. Look at the qobjectdefs.h:

# define SLOT(a)     "1"#a
# define SIGNAL(a)   "2"#a

It just adds 1 or 2. It means that next code is valid and works as expected:

QObject *obj = new QObject;
connect(obj,"2objectNameChanged(QString)",this,"1show()");//suppose this is a pointer to a QDialog subclass
obj->setObjectName("newNAme");

why do most programmers use these macros instead of using like &Obj1::signal

More details here.

Bushido answered 23/7, 2015 at 14:14 Comment(2)
Did you really meant to say "these macros work not only in Qt5"? Or something else?Geognosy
@PeterMortensen Yes, because macros-way works in Qt4 and Qt5, but new-way via pointer-to-method works in Qt5 only, so that's why I wrote like that, devs who works with legacy old code can't use Qt5, so they can't use new way, so they use old way which "work not only in Qt5"Bushido
M
2

To complete TheDarkKnight's answer, it is an excellent practice to refactor legacy code that is using the old Qt 4 SIGNAL and SLOT macros to Qt 5's new syntax using function address.

Suddenly, connection error will appear at compile time instead of at runtime! It's very easy to make a Qt 4 connection error as any spelling mistake will result in such an error. Plus, the name of the function must be the fully qualified name, i.e preceded with the full namespace if any.

Another benefit is the ability to use a lambda for the slot function, which can reduce need of a named function if the slot body is trivial.

Mchail answered 25/10, 2017 at 9:26 Comment(0)
G
0

These macros just convert their parameters to signal/slot-specific strings. The Differences between String-Based and Functor-Based Connections can be found in the docs. In short:

String-based:

  • Type checking is done at Run-time
  • Can connect signals to slots which have more arguments than the signal (using default parameters)
  • Can connect C++ functions to QML functions

Functor-based:

  • Type checking is done at Compile-time
  • Can perform implicit type conversions
  • Can connect signals to lambda expressions
Gibson answered 1/12, 2019 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.