Qt:如何通过像函数一样调用信号来知道插槽是否被信号插槽机制调用

Qt:如何通过像函数一样调用信号来知道插槽是否被信号插槽机制调用,qt,qt-signals,qt-slot,Qt,Qt Signals,Qt Slot,在插槽中,我检查了,但是现在我想直接调用这个插槽,就像调用函数一样 我能知道这个槽在槽里面是怎么叫的吗?通过信号插槽机制或像函数一样简单地调用插槽?您可以在这两种情况下检查发送器()。在通过信号/插槽机制调用插槽的情况下,发送方将返回指针,而作为方法调用时,它将返回空指针 简单的例子: class Test : public QObject { Q_OBJECT signals: void signal(); public slots: void slot() { qD

在插槽中,我检查了,但是现在我想直接调用这个插槽,就像调用函数一样


我能知道这个槽在槽里面是怎么叫的吗?通过信号插槽机制或像函数一样简单地调用插槽?

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

简单的例子:

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

public slots:
    void slot() { qDebug() << sender(); }
};
以及输出:

测试(0xa8e8aff5b0)

QObject(0x0)

  • 将默认参数添加到插槽:

    public slots:
        void slot(bool calledBySignal = true);
    
  • 直接调用插槽时,将参数设置为false:

    void MyClass::method()
    {
        [...]
        slot(false);
        [...]
    }
    
  • connect()
    调用保持原样;不要向信号中添加bool参数,也不要将
    SLOT(SLOT())
    更改为
    SLOT(SLOT(bool))

  • 缺点:很容易忘记设置参数


    如果您的插槽不需要是公共的,因为
    connect()
    ing只能从类内部处理,那么您应该将其设置为私有的,并添加一个要调用的包装器方法,但从类内部调用它时仍然需要一些规则。Johannes的建议可以解决这些问题。

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

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

    if(QObject::senderSignalIndex() == -1){
        //called directly as a function
    } else {
        // invoked via Signal/SLot mechanism
    }
    
    返回调用当前正在执行的插槽的信号的元方法索引,该插槽是sender()返回的类的成员。如果在由信号激活的插槽外部调用,则返回-1

    这看起来是一种清晰的区分方法,与使用
    QObject*QObject::sender()const
    相比,使用空指针不会有麻烦

    问候,,
    Felix

    sender在作为方法调用时不为空。文档中甚至有这样的说明:“如果在由信号激活的插槽中调用,则返回指向发送信号的对象的指针;否则返回0。指针仅在从该对象的线程上下文调用此函数的插槽执行期间有效。”这里的“if called in a slot”大概是指“if called in activation of a slot”。也就是说,if called in a slot作为一个函数直接调用该slot但是从信号调用的另一个插槽,直接调用的插槽将观察到非空返回值。但这不是他想要的。如果不是无效的话,它会使你的解决方案有缺陷。把代码放到另一个函数中,这个函数有一个
    bool fromSignal
    ,用
    true
    从你的槽中调用这个函数,然后直接用
    false
    在别处调用它。@Johanneschaub litb,我认为这是一个很好的答案,比当前的更好。
    if(QObject::senderSignalIndex() == -1){
        //called directly as a function
    } else {
        // invoked via Signal/SLot mechanism
    }