A simple question regarding the new signal/slot syntax in Qt5:
- Are there still benefits for a
Q_OBJECT
-derived class to have public slots:
sections declared?
Note: With the new syntax you're able to connect a signal to any public function of a class or directly implement a C++11 lambda (which can also call some member functions itself).
Qt's new signal/slot syntax
While the answers by vahancho and TheDarkKnight are valid: slots
is not required for connections, but it makes the intent clearer and allows introspection. I think I should list some use cases where you do need slots
.
First please note that you can use slots
, Q_SLOTS
, Q_SLOT
or Q_INVOKABLE
to make a function known to the meta object (introspection) system. Q_INVOKABLE
has the advantage that it can be used on constructors.
And here are the use cases in no particular order:
- Make your code works with Qt 4. Even if Qt 4 is not maintained I think some big company are still using it and it is fairly easy to make a library works with Qt 5 and Qt 4.
- Make the function available in QML (and Qt Quick)
- Make the function available in javascript (Qt Script, Qt WebEngine, etc.)
- Make the function callable with
QMetaObject::invokeMethod()
. An overload that accepts functors will be available in Qt 5.10.
- Make use of
QMetaObject::connectSlotsByName()
. Note that this function should not be used as it can be affected by object name collisions, but it is still the way the Qt widget designer connects the slots it creates.
- Make your class instantiatable with
QMetaObject::newInstance()
.
- And every other use case that requires run-time introspection
you're able to connect a signal to any public function of a class or directly implement a C++11 lambda
Whilst this was made available in Qt 5, which allows for compile-time verification of the slot, as opposed to when using the SIGNAL
and SLOT
macros, it is no longer a requirement to declare a function as a slot to connect to it.
However, for clarity I still do, as it makes the intention of a class clearer for usage, when others come to using the class.
For example:
class Foo : public QObject
{
public:
Foo();
public slots:
void AddData();
private:
void CalculateStuff();
};
Just by looking at the class, we can assume that the function AddData
is designed to be called via a signal; perhaps it executes on a separate thread.
public slots:
etc. declarations still needed for moc introspection if you are going to use the "old" connection style. With the new syntax this declarations do not make any sense, because, as you also noticed, "slots" are called directly by function pointers. "Slots" may even be a non class member functions as well.
However, you still need to declare your signals under signals:
section of your class declaration.
They're still needed for Qml, so that you can connect to C++ slots. However, if you want to call a C++ QObject member function, you can just declare it as Q_INVOKABLE
. You don't need to make it a slot. Although using slots:
might be more readable compared to using Q_INVOKABLE
. Up to you.
They're also needed if you want Designer to see them. Designer has a "signal/slot" editor, and it will not list functions that are not in the slots:
section. However, Designer still uses the old string-based syntax for signals and slots, so I wouldn't recommend using its signal/slot editor.