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

Mar*_*ngs 2 c++ qt signals-slots qwidget moc

我“不小心”将信号连接到QWidget::setToolTip()

bool ok = connect(source, &Source::textSignal, widget, &QWidget::setToolTip);
Q_ASSERT(ok);
Run Code Online (Sandbox Code Playgroud)

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

自己试试:
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();
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

    Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
Run Code Online (Sandbox Code Playgroud)

文档没有提到这一点。

Mar*_*ngs 6

我在woboq.com 上找到了一个答案(“连接到任何函数”及之前)

[...]

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 &);
};
Run Code Online (Sandbox Code Playgroud)

连接到任何功能

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

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

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

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

=>函数指针不需要声明为public slots:可调用的。

  • 请注意,这仅适用于 Qt5。 (2认同)