Qt信号能否返回值? [英] Can Qt signals return a value?

查看:5220
本文介绍了Qt信号能否返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Boost.Signals 允许使用槽的返回值形成的各种策略信号的返回值。例如。添加它们,形成一个向量,或返回最后一个。



共同的智慧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 :: QueuedConnection 模式( QPrintPreviewWidget API ,但仍然存在,是有用的)。但是 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信号能否返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆