在一个插槽内,我检查了QObject::sender()
但现在我想像函数一样直接调用这个插槽。
我可以知道这个插槽是如何在插槽内部调用的吗?是通过信号槽机制还是简单地像函数一样调用槽?
在一个插槽内,我检查了QObject::sender()
但现在我想像函数一样直接调用这个插槽。
我可以知道这个插槽是如何在插槽内部调用的吗?是通过信号槽机制还是简单地像函数一样调用槽?
将默认参数添加到您的插槽:
public slots:
void slot(bool calledBySignal = true);
直接调用slot时设置参数为false:
void MyClass::method()
{
[...]
slot(false);
[...]
}
保持connect()
通话不变;不要在信号中添加 bool 参数,也不要更改SLOT(slot())
为SLOT(slot(bool))
.
缺点:容易忘记设置参数。
如果您的插槽不需要公开,因为connect()
它仅在类内部处理,您应该将其设为私有并添加一个要调用的包装器方法,但在调用它时仍然需要一些纪律从课堂内部。Johannes 的建议将解决这些问题。
您可以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)
区分直接函数调用与信号/插槽调用的另一个想法:
使用方法 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
.
问候,菲利克斯