Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Public functions versus public slots

In my one year of Qt programming, I have learnt a lot about signals and slots. But not enough...

http://doc.qt.io/qt-5/signalsandslots.html

Slots can be used for receiving signals, but they are also normal member functions.

So... Is there any reason not to declare every single function in a class that inherits from QObject, as a slot, whether it needs to be one or not ?

In the link above, they give an example:

A small QObject-based class might read:

#include <QObject>

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }

public slots:
    void setValue(int value);

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

Why define the value() function as a plain function and not a slot ? Would there be any negative results if they did make it a slot ?

like image 305
Thalia Avatar asked Mar 08 '16 22:03

Thalia


1 Answers

Back in the olden days, you had no choice but to use slots if you want to connect to signals. This is no longer the case in Qt 5, where connections can be made to regular member functions or even free functions or lambdas.

Declaring a slot registers that function into that particular object's meta data, making it readily available to all of Qt's functionality which relies on the meta object. Other than that, it is a regular member function as the documentation states. There is nothing special in the slot function itself, the difference is in the generation of meta data for it in the meta object.

This means that declaring slots comes at some cost, albeit a small one, both in compilation time and executable size. I'd say it is overkill to have all your public functions as slots. It would be more efficient to only use slots when you actually need slots, if it can't work with a regular function, make it a slot.

Also, note that in almost all of the cases, signals are declared with a return type void. This has to do with the typical usage case of signals - they can often pass a parameter, but rarely return anything. Even though it is possible to return a value through a signal connected to a slot, this is used extremely rarely. So it doesn't make a lot of sense to declare a function that returns something as a slot you intend to connect to, as the very fact it returns a value means it will most likely not be used in the typical signal/slot context. That's why the getter is not a slot in that example. The setter as a slot is redundant in Qt 5, and is probably the product of this example code dating back to Qt 4.

Lastly, separating slots from regular public functions is a good way to illustrate intent, or the "API" of that class if you will. For example, I mostly use slots when extending QML, so I don't have to mark every function explicitly as invokable - unlike the scenario mentioned in the above paragraph, such slots often return stuff, but they aren't really used in connections. This way I get a clear overview of the design of the interface the class provides.

like image 164
dtech Avatar answered Nov 15 '22 21:11

dtech