【问题标题】:Q_RETURN_ARG and QQmlComponent - component not readyQ_RETURN_ARG 和 QQmlComponent - 组件未准备好
【发布时间】:2014-01-09 03:05:39
【问题描述】:

我花了 3 天时间仔细检查了我在互联网上找到的关于 Q_RETURN_ARG 的最佳 reference 材料。我已经包含了QQmlComponent。在 C++ 上使用它来发送变量以在 QML 上显示时,事情并不总是像看起来那样。可能是因为 Qt5 比较新,所以我们可以依赖的材料还不是很多。

基本上,代码编译没有问题。当我要求它运行时,它会将 qml 页面毫无问题地呈现给设备,然后它得到错误:

QQmlComponent: Component is not ready
main.cpp:33 (int main(int, char**)): Got QML return: ""

除了文件 invoke.pro 和 myapplication.cpp 之外,这里是我正在尝试解决的小示例的关键部分,基于 postQt5 documentationICS tutorialpostlink:

./myapplication.h

#include <QObject>
#include <QDebug>
#include <QQmlComponent>

class MyApplication : public QObject
{   Q_OBJECT
    public:
        explicit MyApplication(QObject *parent = 0);
        ~MyApplication(void) {}    
        QObject *object;
        QQmlComponent *component;

        void loadComponent(void)
        {   QQmlEngine engine;
            QQmlComponent *component = new QQmlComponent(&engine);
            component->loadUrl(QStringLiteral("qml/invoke/main.qml"));

            if(!component->isReady()){
                qWarning("qPrintable: %s", qPrintable(component->errorString()));
            }

            if (component->isLoading()){
                cout <<"==== component->isLoading ====";
                QObject::connect(component,
                                 SIGNAL(statusChanged()),
                                 this,
                                 SLOT(continueLoading()));
            }
            else{
                cout <<"==== component is not Loading ====";
                continueLoading();
            }
        }    
    signals:

    public slots:
        void continueLoading()
        {   QQmlEngine engine;
            QQmlComponent *component = new QQmlComponent(&engine);
            component->loadUrl(QStringLiteral("qml/invoke/main.qml"));

            if (component->isError()) {
                qWarning() << "component->isError()="<< component->errors();
            } else {
                object = component->create();
                cout <<"object created";
            }
        }    
};

./main.qml

import QtQuick 2.0
Rectangle {
    width: 360
   height: 360
    Item {
        function myQmlFunction(msg_cpp) {
            console.log("Got msg_cpp:", msg_cpp)
            return "output"
        }
    }
}

./main.cpp

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>
#include <QQmlEngine>
#include <QtQml>
#include <QDeclarativeEngine>
#include <QtCore>
#include <QtQuick/QtQuick>
#include <QQmlComponent>
#include <QtQml/qqml.h>
#include "myapplication.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/invoke/main.qml"));

    MyApplication *myClass = new MyApplication();
    myClass->loadComponent();

    QObject *object=myClass->object;

    QVariant returnedValue;
    QVariant msg_cpp = "C++ message";
    QMetaObject::invokeMethod(object,
                              "myQmlFunction",
                              Q_RETURN_ARG(QVariant, returnedValue),
                              Q_ARG(QVariant, msg_cpp));
    qDebug() << "Got QML return:" << returnedValue.toString();

    viewer.showExpanded();
    delete object;
    return app.exec();
}

这给出了错误:

loadComponent()): qPrintable: file://qml/invoke/main.qml:-1 File not found
continueLoading()): component->isError()= (file://qml/invoke/main.qml: File not found) 
main.cpp:36 (int main(int, char**)): Got QML return: "" 

我注意到 main.qml 旨在使用“QtQuick2ApplicationViewer”而不是“QQmlEngine”在 Android 上加载。是否应该根本不使用“QQmlEngine”来加载 main.qml 以尝试让 Q_RETURN_ARG 运行 - 在处理 Android 时,这就是为什么“QQmlComponent 组件”没有加载的原因?如果我尝试使用“QtQuick2ApplicationViewer 查看器”替换“QQmlComponent 组件”的“QQmlEngine 引擎”,它会显示:“没有匹配函数调用 QQmlComponent”。

任何建议如何初始化 QQmlComponent,让 Q_RETURN_ARG 开始工作?谢谢!

【问题讨论】:

  • 你为什么不使用 statusChanged 信号并连接?我认为您未能从 Qt 文档中复制并粘贴示例。
  • 刚刚添加了建议和附加评论。
  • 你有两个问题。您在信号后缺少右括号。您没有将“QQmlComponent::Status”参数类型传递给信号,也没有传递给槽。
  • 谢谢。你对支架是正确的。如您在更新中看到的那样发送信号和插槽。 main.qml 仍然没有找到。

标签: android c++ qt android-ndk qml


【解决方案1】:

我快速查看了您的代码并对其进行了一些更改,但它缺少一些大(BIG!)QT/编码概念。

使其工作的一些关键错误:

  • 文件错误只是正确设置文件路径的问题。
  • 加载源需要时间,而不是未准备好的急切序列 -> 使用其他 QQmlEngine 再次加载。 (这在我的代码中没有固定)
  • myQmlFunction 需要在 QML 树中获取上层,或一些其他类型的参考帮助。
  • ...

您可以在这里查看完整代码。

http://pastebin.com/PRLBtKWU

我建议你看看这本书 http://qmlbook.org/ 并使用当前 QT 版本的 QT 示例进行练习。

【讨论】:

  • 谢谢!我非常感谢您的反馈。今天我有机会试试你的例子。我遵循完全相同的步骤重用您发布的相同编辑代码。从第 66 行我得到了错误: ./qt5app/myobject.cpp:4: error: 'myobject' does not name a type myobject::myobject(QObject *parent) : :-1: error: [myobject.o] 错误1. 有什么建议吗?
  • 可能是区分大小写的错误吗? myobject 在 c++ 代码中必须是 MyObject,但文件名为 myobject。
  • 再次感谢 - 你对大写的 MyObject 解决了它是对的。现在在第 77 行,我收到了另一个错误: ./qt5app/myobject.cpp:15 (void MyObject::loadComponent()): qPrintable: file:///data/data/org.qtproject.example.qt5app/files /qml/qt5app/main.qml:-1 找不到文件。有什么建议吗?
  • 缺少 qml 文件,我已将其粘贴到 pastebin 中。
  • 一定是路径问题,我已经用我的目录树更新了 pastebin。
猜你喜欢
  • 1970-01-01
  • 2017-02-22
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多