問題描述
Boost.Signals 允許 各種策略使用槽的返回值來形成信號的返回值.例如.將它們相加,形成一個 vector
,或者返回最后一個.
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.
常識(在 Qt 文檔 中表達)是 Qt 信號不可能做到這一點.
The common wisdom (expressed in the Qt documentation ) is that no such thing is possible with Qt signals.
但是,當我在以下類定義上運行 moc 時:
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();
};
moc 不僅沒有抱怨具有非 void 返回類型的信號,而且似乎以一種允許返回值傳遞的方式積極實現它:
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;
}
所以:根據文檔,這件事是不可能的.那么moc在這里做什么?
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?
我不是在要求解決方法,所以請不要提供任何方法.
I'm not asking for workarounds, so please don't provide any.
它顯然在 Qt::QueuedConnection
模式(也不是 QPrintPreviewWidget API,但它仍然存在并且很有用).但是 Qt::DirectConnection
和 Qt::BlockingQueuedConnection
(或 Qt::AutoConnection
,當它解析為 Qt::直接連接
).
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:
這是一個簡單的類定義(main.cpp
):
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"
當 main 運行時,它會構建一個測試類.構造函數將兩個插槽連接到 testSignal 信號,然后發出信號.它從調用的插槽中捕獲返回值.
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.
不幸的是,您只能獲得最后一個返回值.如果你評估上面的代碼,你會得到:testSlot2",來自信號連接槽的最后一個返回值.
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.
這就是原因.Qt 信號是信號模式的語法糖接口.插槽是信號的接收者.在直接連接的信號槽關系中,你可以認為它類似于(偽代碼):
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
顯然,moc 在這個過程中做了更多的工作(基本的類型檢查等),但這有助于描繪畫面.
Obviously the moc does a little more to help in this process (rudimentary type checking, etc), but this helps paint the picture.
這篇關于Qt 信號可以返回一個值嗎?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!