Mar*_*utz 51 c++ qt return-value signals-slots boost-signals
Boost.Signals允许使用槽的返回值的各种策略来形成信号的返回值.例如,添加它们,形成vector它们,或返回最后一个.
常见的智慧(在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();
};
Run Code Online (Sandbox Code Playgroud)
不仅没有moc抱怨具有非void返回类型的信号,它似乎以允许返回值传递的方式主动实现它:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
所以:根据文档,这件事是不可能的.那么moc在这做什么?
插槽可以有返回值,那么我们可以将带有返回值的插槽连接到具有返回值的信号吗?毕竟,这可能吗?如果是这样,它有用吗?
编辑:我不是要求解决方法,所以请不要提供任何解决方法.
编辑:它显然在Qt::QueuedConnection模式中没用(QPrintPreviewWidget API也不是,但它仍然存在并且很有用).但是什么Qt::DirectConnection和Qt::BlockingQueuedConnection(或者Qt::AutoConnection,当它解决时Qt::DirectConnection).
jsh*_*rer 38
好.所以,我做了一些调查.似乎这是可能的.我能够发出信号,并从信号连接的插槽中接收值.但是,问题是它只返回多个连接插槽的最后一个返回值:
这是一个简单的类定义(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"
Run Code Online (Sandbox Code Playgroud)
主运行时,它构造一个测试类.构造函数将两个插槽连接到testSignal信号,然后发出信号.它从被调用的槽中捕获返回值.
不幸的是,您只能获得最后的返回值.如果你评估上面的代码,你会得到:"testSlot2",来自信号连接槽的最后一个返回值.
这就是原因.Qt信号是信令模式的语法糖界面.插槽是信号的接收者.在直接连接的信号槽关系中,您可以将其视为(伪代码):
foreach slot in connectedSlotsForSignal(signal):
value = invoke slot with parameters from signal
return value
Run Code Online (Sandbox Code Playgroud)
显然,moc在这个过程中做了一点帮助(基本类型检查等),但这有助于绘制图片.
不,他们不能.
Boost::signals与Qt中的完全不同.前者提供了高级回调机制,而后者实现了信令习惯用法.在多线程环境中,Qt(交叉线程)信号依赖于消息队列,因此它们在一些(发射器线程未知)的时间点被异步调用.