Qt:槽返回值的含义?

时间:2008-09-22 02:12:19

标签: c++ qt signals-slots

根据文档,插槽的返回值并不意味着什么 然而在生成的moc代码中,我看到如果一个槽返回一个值,则该值用于某些东西。知道它做了什么吗?


这是我正在谈论的一个例子。这是从moc生成的代码中获取的。 'message'是一个不返回任何内容的插槽,'selectPart'被声明为返回int。

case 7: message((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])));
    if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; }  break;

4 个答案:

答案 0 :(得分:12)

通过Qt源看来,当从QMetaObject :: invokeMethod调用一个槽时,可以指定返回类型并获得返回值。 (看看Qt帮助中的invokeMethod)

我找不到很多在Qt源中实际使用的例子。我找到的是

bool QAbstractItemDelegate::helpEvent 

这是一个带有返回类型的插槽,从

调用
QAbstractItemView::viewportEvent

使用invokeMethod。

我认为插槽的返回值仅在直接调用函数时(当它是普通的C ++函数时)或使用invokeMethod时才可用。我认为这实际上是用于内部Qt功能,而不是在使用Qt的程序中正常使用。

编辑: 对于示例案例:

case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])), *reinterpret_cast< int(*)>(_a[2])));
if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; }  break;

vector _a是传递给qt_metacall的参数列表。这是由QMetaObject :: invokeMethod传递的。因此,moc生成的代码中的返回值被保存并传递回调用者。因此,对于正常的信号槽交互,返回值根本不用于任何事物。但是,该机制存在,因此如果通过invokeMethod调用插槽,则可以访问插槽的返回值。

答案 1 :(得分:12)

仅当您要将插槽作为普通成员函数调用时,返回值才有用:

class MyClass : public QObject {
    Q_OBJECT
public:
    MyClass(QObject* parent);
    void Something();
public Q_SLOTS:
    int Other();
};

void MyClass::Something() { int res = this->Other(); ... }

编辑:似乎这不是返回值的唯一使用方式,QMetaObject :: invokeMethod方法可用于调用插槽并获取返回值。虽然看起来这样做有点复杂。

答案 2 :(得分:6)

在处理qtscript JavaScript QtPython等动态语言时非常有用。使用这种语言/绑定,您可以使用MetaObject提供的接口使用C ++ QObject。您可能知道,只有信号和插槽由moc解析并生成MetaObject描述。因此,如果您使用来自javascript绑定的C ++ QObject,您将只能调用插槽,并且您将需要返回值。通常,动态语言的Qt绑定提供了一些访问普通方法的工具,但这个过程肯定更加模糊。

答案 3 :(得分:4)

所有插槽都在QMetaObject中公开,可以通过反射接口访问对象。

例如,QMetaObject::invokeMethod()采用QGenericReturnArgument参数。所以我相信这不是用于显式插槽使用,而是用于一般的方法的动态调用。 (还有其他方法可以将方法公开给QMetaObject,而不是将它们放入插槽中。)

例如,invokeMethod函数被各种动态语言(如QML和Javascript)用于调用QObject:s的方法。 (还有一个名为PythonQt的Python-Qt桥使用它。不要与PyQt混淆,后者是一个完整的包装器。)

在Qt应用程序内的线程之间进行同步调用时使用返回值(通过invokeMethod支持并将连接类型设置为Qt::BlockingQueuedConnection,其中包含以下文档:

  

与QueuedConnection相同,但当前线程阻塞直到   槽返回。   此连接类型仅应用于发射器和接收器的位置   在...   不同的线程。注意:违反此规则可能会导致您的应用程序   陷入僵局。