C 信号到 Qt 中的 QML 插槽

新手上路,请多包涵

我想将信号从 C++ 发送到我的 QML 文件中的插槽。我已经让它在没有原始类型参数的情况下工作,但如果我想向我的 QML Slot 发送 QString 我在连接时会出错。

我在 main.cpp 中连接

QObject *contentView = rootObject->findChild<QObject*>(QString("contentView"));
QObject::connect(&myObj,      SIGNAL(finishedGatheringDataForItem(QString)),
                 contentView, SLOT(updateViewWithItem(QString)));

我的 qml 文件的相关部分

Rectangle {
        objectName: "contentView"
        function updateViewWithItem(string) { console.log('got some Items'); }  // slot
}

错误:

 Object::connect: No such slot QDeclarativeRectangle_QML_2::updateViewWithItem(QString)

原文由 alex 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 962
2 个回答

我认为最好查看本教程:

http://doc.qt.io/qt-4.8/qtbinding.html

特别是本节:

http://doc.qt.io/qt-4.8/qtbinding.html#receiving-signals

我认为您在这种情况下的错误可能是您没有将其声明为插槽,或者您没有使其可调用。 Qt 教程中解释了这两个选项。

此外,您需要使用 QVariant 在 C++ 和 QML 之间交换数据。您还可以注册类型,例如小部件和东西,以便您可以在 QML 中将它们用作“原生”类型,如矩形。在大多数情况下,不建议这样做,除非您需要某些特定的外部类或某些无法在 QML 界面中显示的数据。

QVariant 的原因是 QML 的基于脚本的方法。 QVariant 基本上包含您的数据和数据类型的描述,以便 QML 知道如何正确处理它。这就是为什么您必须在 QML 中使用 String、int 等指定参数的原因。但是与 C++ 的原始数据交换仍然是 QVariant

我之前用过qmlRegisterType,但是对于简单的数据类型来说,它是一个非常不方便的解决方案。它更适合用于更复杂的数据,例如 QML 本身不支持或扩展的自定义小部件、画布或视频元素 QStandardItemModels 。这是在 QML 和 C++ 之间交换数据的一种更方便的方式,并且在第一个实例中不需要 Signals 或 Slots,因为 QStandardItemModel 会自动更新 GUI。要使用 QStandardItemModel,您需要使用 qmlRegisterType.. 注册类型。然后可以在基于模型的视图中使用模型,例如 ListView 等。

我附上了这个主题的教程,它描述了如何使用 QListModel。

http://doc.qt.io/qt-4.8/qdeclarativemodels.html

原文由 mmoment 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于那些也偶然发现这个问题的人,我想说一切都简单得多。您只需要来自 C++ 的信号具有 QVariant 参数。例如:

 QObject::connect(&recipient, SIGNAL(resTalk(QVariant)), engine.rootObjects().at(0)->findChild<QObject*>("winSettings"),
                     SLOT(showWithErrorNetwork(QVariant)));

我的信号声明如下:

 signals:
    void resTalk(QVariant res);

所以我打电话给信号:

 emit resTalk(true); //For more complex types, use  'emit yourSignal(QVariant(yourArg))'

这是我在 QML 中的插槽:

     function showWithErrorNetwork(isNoError=false) {
        if(!isNoError) {
            visible = true
            warningText.text = "Network error. Check the data."
            warningText.visible = true
        }
    }

原文由 Сергей Воронцов 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题