I 'accidentally' connected a signal to QWidget::setToolTip()
:
bool ok = connect(source, &Source::textSignal, widget, &QWidget::setToolTip);
Q_ASSERT(ok);
... and it worked. Not only did the connection succeed, the function was also invoked correctly.
Try it yourself:
main.cpp
#include <QApplication>
#include <QLineEdit>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineEdit le;
bool ok = QObject::connect(&le, &QLineEdit::textChanged, &le, &QWidget::setToolTip);
Q_ASSERT(ok);
le.show();
return a.exec();
}
setToolTip()
is not declared as a slot
.
from qwidget.h:
// [...]
public Q_SLOTS: // start of Q_SLOTS
void setWindowTitle(const QString &);
#ifndef QT_NO_STYLE_STYLESHEET
void setStyleSheet(const QString& styleSheet);
#endif
public: // from my understanding, this should end the Q_SLOTS region
#ifndef QT_NO_STYLE_STYLESHEET
QString styleSheet() const;
#endif
QString windowTitle() const;
// [...]
bool isWindowModified() const;
#ifndef QT_NO_TOOLTIP
void setToolTip(const QString &); // no Q_SLOTS!?
QString toolTip() const;
void setToolTipDuration(int msec);
int toolTipDuration() const;
#endif
So I wondered: Is this because toolTip
is declared as Q_PROPERTY
?
Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
The documentation doesn't mention that.
I found an answer at woboq.com ('Connecting to any function' and preceding):
[...]
class Test : public QObject { Q_OBJECT public: Test() { connect(this, &Test::someSignal, this, &Test::someSlot); } signals: void someSignal(const QString &); public: void someSlot(const QVariant &); };
Connecting to any function
As you might have seen in the previous example, the slot was just declared as public and not as slot. Qt will indeed call directly the function pointer of the slot, and will not need moc introspection anymore. (It still needs it for the signal)
But what we can also do is connecting to any function or functor:
static void someFunction() { qDebug() << "pressed"; } // ... somewhere else QObject::connect(button, &QPushButton::clicked, someFunction);
This can become very powerful when you associate that with boost or tr1::bind.
=> A function pointer doesn't need to be declared as public slots:
to be invokable.