2

在一个插槽内,我检查了QObject::sender()但现在我想像函数一样直接调用这个插槽。

我可以知道这个插槽是如何在插槽内部调用的吗?是通过信号槽机制还是简单地像函数一样调用槽?

4

3 回答 3

3
  1. 将默认参数添加到您的插槽:

    public slots:
        void slot(bool calledBySignal = true);
    
  2. 直接调用slot时设置参数为false:

    void MyClass::method()
    {
        [...]
        slot(false);
        [...]
    }
    
  3. 保持connect()通话不变;不要在信号中添加 bool 参数,也不要更改SLOT(slot())SLOT(slot(bool)).

缺点:容易忘记设置参数。

如果您的插槽不需要公开,因为connect()它仅在类内部处理,您应该将其设为私有并添加一个要调用的包装器方法,但在调用它时仍然需要一些纪律从课堂内部。Johannes 的建议将解决这些问题。

于 2016-09-04T20:40:49.337 回答
2

您可以sender()在这两种情况下检查。如果通过信号/槽机制调用槽,则发送方将返回一个指针,而当作为方法调用时,它将返回空指针。

简单的例子:

class Test : public QObject
{
    Q_OBJECT
signals:
    void signal();

public slots:
    void slot() { qDebug() << sender(); }
};

以及用途:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Test test;
    Test test2;

    QObject::connect(&test, &Test::signal, &test2, &Test::slot);

    test.signal(); //slot is caled by signal
    test2.slot(); //slot is called as method directly

    return a.exec();
}

和输出:

测试(0xa8e8aff5b0)

QObject(0x0)

于 2016-09-04T07:40:15.913 回答
0

区分直接函数调用与信号/插槽调用的另一个想法:

使用方法 int QObject::senderSignalIndex() const 并检查 -1

if(QObject::senderSignalIndex() == -1){
    //called directly as a function
} else {
    // invoked via Signal/SLot mechanism
}

返回调用当前执行槽的信号的元方法索引,它是 sender() 返回的类的成员。如果在由信号激活的槽之外调用,则返回 -1。

请参阅 Qt 4.8 文档

这看起来是一种清晰的区分方式,与使用QObject * QObject::sender() const.

问候,菲利克斯

于 2018-07-17T09:30:53.527 回答