【问题标题】:Qt: meaning of slot return value?Qt:槽返回值的含义?
【发布时间】:2010-09-11 21:19:59
【问题描述】:

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

【问题讨论】:

    标签: c++ qt signals-slots


    【解决方案1】:

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

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

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

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

    与 QueuedConnection 相同,除了当前线程阻塞,直到 插槽返回。 这种连接类型只能用于发射器和接收器 在 不同的线程。注意:违反此规则可能会导致您的申请 陷入僵局。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 看看 QWebFrame::addToJavaScriptWindowObject 并考虑如何让该框架中的 javascript 从您添加的对象中获取数据。
      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

        bool QAbstractItemDelegate::helpEvent 
        

        这是一个有返回类型的槽,被调用

        QAbstractItemView::viewportEvent
        

        使用调用方法。

        我认为只有在直接调用函数时(当它是普通的 C++ 函数时)或使用 invokeMethod 时,才能使用 slot 的返回值。我认为这实际上是用于 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 调用 slot,则存在这种机制,因此可以访问来自 slot 的返回值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-07
          • 1970-01-01
          • 1970-01-01
          • 2015-06-20
          相关资源
          最近更新 更多