为什么可以连接到未声明为Q_SLOTS的函数?

时间:2018-02-16 08:11:22

标签: c++ qt signals-slots qwidget moc

我'意外'将信号连接到QWidget::setToolTip()

bool ok = connect(source, &Source::textSignal, widget, &QWidget::setToolTip);
Q_ASSERT(ok);

......它奏效了。不仅连接成功,还正确调用了该函数。

亲自尝试:
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()未声明为slot

来自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

所以我想知道:这是因为toolTip被声明为Q_PROPERTY吗?

    Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)

文档没有提到这一点。

2 个答案:

答案 0 :(得分:4)

我在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 &);
};
     

连接任何功能

     

正如您在上一个示例中看到的那样,插槽只是声明为public而不是slot。 Qt确实会直接调用插槽的函数指针,不再需要moc内省了。 (它仍然需要信号)

     

但我们还可以做的是连接任何函数或函子:

static void someFunction() {
    qDebug() << "pressed";
}
// ... somewhere else
    QObject::connect(button, &QPushButton::clicked, someFunction);
     

当你将它与boost或tr1 :: bind相关联时,这会变得非常强大。

=&GT; 函数指针不需要声明为public slots:即可调用。

答案 1 :(得分:0)

有不同的连接方式(阅读QObject文档),有些需要函数名称,有些是元方法,有些是指向成员的指针和一些仿函数。您只是使用接受指向成员的指针的那个。

  

QMetaObject :: Connection connect(const QObject * sender,const char   * signal,const QObject * receiver,const char * method,Qt :: ConnectionType type = Qt :: AutoConnection)

     

QMetaObject :: Connection connect(const QObject * sender,const   QMetaMethod&amp; signal,const QObject * receiver,const QMetaMethod   &amp;方法,Qt :: ConnectionType type = Qt :: AutoConnection)

     

QMetaObject :: Connection connect(const QObject * sender,   PointerToMemberFunction信号,const QObject *接收器,   PointerToMemberFunction方法,Qt :: ConnectionType type =   Qt的::自动连接)

     

QMetaObject :: Connection connect(const QObject   * sender,PointerToMemberFunction信号,Functor仿函数)

     

QMetaObject :: Connection connect(const QObject * sender,   PointerToMemberFunction信号,const QObject * context,Functor   仿函数,Qt :: ConnectionType type = Qt :: AutoConnection)