问题描述
允许信号的返回值。例如。添加它们,形成一个向量
,或返回最后一个。
共同的智慧Qt文档 的一些答案)是没有这样的事情是可能与Qt信号。
但是,当我对下面的类定义运行moc:
class Object:public QObject {
Q_OBJECT
public:
explicit Object(QObject * parent = 0)
:QObject(parent){}
public Q_SLOTS:
void voidSlot();
int intSlot();
Q_SIGNALS:
void voidSignal();
int intSignal();
};
不仅moc抱怨信号与非void返回类型,积极地实现它以允许返回值通过:
//信号1
int Object :: intSignal()
{
int _t0;
void * _a [] = {const_cast< void *>(reinterpret_cast< const void *>(& _t0))};
QMetaObject :: activate(this,& staticMetaObject,1,_a);
return _t0;
}
所以:根据文档,这是不可能的。那么这里的moc是做什么的呢?
,因此我们可以将一个具有返回值的插槽与具有返回值的信号连接?可能是可能的,毕竟?如果是,是否有用?
编辑:我不是要求解决方法,因此请不要提供任何。 >
EDIT:显然在模式(,但仍然存在,是有用的)。但是 Qt :: DirectConnection
和 Qt :: BlockingQueuedConnection
(或 Qt :: AutoConnection
,当它解析为 Qt :: DirectConnection
)。
确定。所以,我做了一个更多的调查。似乎这是可能的。我能够发射信号,并从信号连接到的插槽接收值。但是,问题是它只返回多个连接的槽的最后一个返回值:
这里有一个简单的类定义( main.cpp
):
#include< QObject>
#include< QDebug>
class TestClass:public QObject
{
Q_OBJECT
public:
TestClass();
Q_SIGNALS:
QString testSignal();
public Q_SLOTS:
QString testSlot1(){
return QLatin1String(testSlot1);
}
QString testSlot2(){
return QLatin1String(testSlot2);
}
};
TestClass :: TestClass(){
connect(this,SIGNAL(testSignal()),this,SLOT(testSlot1()));
connect(this,SIGNAL(testSignal()),this,SLOT(testSlot2()));
QString a = emit testSignal();
qDebug()<<一个;
}
int main(){
TestClass a;
}
#includemain.moc
主要运行,它构造一个测试类。构造函数将两个插槽连接到testSignal信号,然后发出信号。它捕获来自调用的插槽的返回值。
不幸的是,您只能获得最后一个返回值。如果你评估上面的代码,你会得到:testSlot2,从信号的连接槽的最后一个返回值。
这里是为什么。 Qt信号是信令模式的语法糖化接口。插槽是信号的接收者。在直接连接的信号槽关系,你可以认为它类似于(伪代码):
foreach slot in connectedSlotsForSignal (信号):
value =具有来自信号的参数的调用槽
返回值
显然,moc在这个过程中有更多的帮助(基本类型检查等),但这有助于绘制图片。
Boost.Signals allows various strategies of using the return values of slots to form the return value of the signal. E.g. adding them, forming a vector
out of them, or returning the last one.
The common wisdom (expressed in the Qt documentation [EDIT: as well as some answers to this question ]) is that no such thing is possible with Qt signals.
However, when I run the moc on the following class definition:
class Object : public QObject {
Q_OBJECT
public:
explicit Object( QObject * parent=0 )
: QObject( parent ) {}
public Q_SLOTS:
void voidSlot();
int intSlot();
Q_SIGNALS:
void voidSignal();
int intSignal();
};
Not only doesn't moc complain about the signal with the non-void return type, it seems to actively implement it in such a way as to allow a return value to pass:
// SIGNAL 1
int Object::intSignal()
{
int _t0;
void *_a[] = { const_cast<void*>(reinterpret_cast<const void*>(&_t0)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
return _t0;
}
So: according to the docs, this thing isn't possible. Then what is moc doing here?
Slots can have return values, so can we connect a slot with a return value to a signal with a return value now? May that be possible, after all? If so, is it useful?
EDIT: I'm not asking for workarounds, so please don't provide any.
EDIT: It obviously isn't useful in Qt::QueuedConnection
mode (neither is the QPrintPreviewWidget API, though, and still it exists and is useful). But what about Qt::DirectConnection
and Qt::BlockingQueuedConnection
(or Qt::AutoConnection
, when it resolves to Qt::DirectConnection
).
OK. So, I did a little more investigating. Seems this is possible. I was able to emit a signal, and receive value from the slot the signal was connected to. But, the problem was that it only returned the last return value from the multiple connected slots:
Here's a simple class definition (main.cpp
):
#include <QObject>
#include <QDebug>
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass();
Q_SIGNALS:
QString testSignal();
public Q_SLOTS:
QString testSlot1() {
return QLatin1String("testSlot1");
}
QString testSlot2() {
return QLatin1String("testSlot2");
}
};
TestClass::TestClass() {
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot1()));
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot2()));
QString a = emit testSignal();
qDebug() << a;
}
int main() {
TestClass a;
}
#include "main.moc"
When main runs, it constructs one of the test classes. The constructor wires up two slots to the testSignal signal, and then emits the signal. It captures the return value from the slot(s) invoked.
Unfortunately, you only get the last return value. If you evaluate the code above, you'll get: "testSlot2", the last return value from the connected slots of the signal.
Here's why. Qt Signals are a syntax sugared interface to the signaling pattern. Slots are the recipients of a signal. In a direct connected signal-slot relationship, you could think of it similar to (pseudo-code):
foreach slot in connectedSlotsForSignal(signal):
value = invoke slot with parameters from signal
return value
Obviously the moc does a little more to help in this process (rudimentary type checking, etc), but this helps paint the picture.
这篇关于Qt信号能否返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!