26

根据文档,插槽的返回值没有任何意义。
然而,在生成的 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

4 回答 4

15

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

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 方法可用于调用插槽并获取返回值。虽然它看起来有点复杂。

于 2008-09-30T17:25:34.083 回答
12

查看 Qt 源代码,似乎当从 QMetaObject::invokeMethod 调用插槽时,可以指定返回类型并获得返回值。(查看 Qt 帮助中的 invokeMethod )

我找不到很多实际在 Qt 源代码中使用的示例。我发现的一个是

bool QAbstractItemDelegate::helpEvent 

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

QAbstractItemView::viewportEvent

使用调用方法。

我认为只有在直接调用函数时(当它是普通的 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;

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

于 2008-09-22T03:00:37.797 回答
6

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

于 2010-02-01T14:59:48.427 回答
5

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

例如,QMetaObject::invokeMethod()接受一个QGenericReturnArgument参数。所以我相信这不是为了显式使用插槽,而是为了动态调用一般的方法。(除了将方法放入槽之外,还有其他方法可以将方法暴露给 QMetaObject。)

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

当在 Qt 应用程序中跨线程进行同步调用时使用返回值(通过 invokeMethod 支持并将连接类型设置为Qt::BlockingQueuedConnection,它具有以下文档:

与 QueuedConnection 相同,除了当前线程阻塞,直到槽返回。这种连接类型应该只用于发射器和接收器在不同线程中的情况。注意:违反此规则可能会导致您的应用程序死锁。

于 2011-01-07T13:31:30.073 回答