在插槽内,我检查QObject::sender()
,但现在我想像调用函数一样直接调用该插槽。
我能知道这个槽是如何在槽内部被调用的吗?是通过信号槽机制还是简单地像调用函数一样调用槽?
您可以在这两种情况下检查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();
}
输出:
测试(0 xa8e8aff5b0)QObject (0 x0)
-
添加一个默认参数到您的插槽:
public slots: void slot(bool calledBySignal = true);
-
直接调用槽位时设置为false:
void MyClass::method() { [...] slot(false); [...] }
-
保持
connect()
呼叫不变; 不给信号增加bool参数,也不将
SLOT(slot())
改为SLOT(slot(bool))
。缺点:容易忘记设置参数。
如果您的插槽不需要是公共的,因为connect()
只从类内部处理它,您应该将其设置为私有并添加一个要调用的包装器方法,但是在从类内部调用它时仍然需要一些规则。Johannes的建议将解决这些问题。
另一种区分直接函数调用与信号/槽调用的方法:
使用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
相比,使用空指针不会有任何麻烦。
问候,Felix