代码
Qml
我假设给出的 qml 代码实际上属于 MyItem.qml 而不是 main.qml。
您的 Qml 文件生成了编译时错误。函数应该放在对象内部,就像这样
// MyItem.qml
import QtQuick 2.0
Text {
id: textbox
text: "nothing"
function myQmlFunction(msg) {
console.log("Got message:", msg)
textbox.text = msg
return "some return value"
}
}
我不确定你是如何编译你的项目而不产生错误的,但我猜也是
- 您的 QtCreator/Qt 版本与我的不同(极不可能的原因); 或
- 您试图使您的代码最小化并且最初有一个父级。
我相信你对 Qml 有足够的了解,所以我不打算深入这个。
C++
在 C++ 方面,我不得不摆弄调试输出以查看问题所在。这是我的main.cpp:
// main.cpp
#include <QApplication>
#include <QDebug>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QQuickItem>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); // Qt requires an instance of QApplication
QQmlEngine *engine = new QQmlEngine;
QString projectPath = "/Users/user/full/path/to/your/project"; // I'm on a Mac, but replace
// with the appropriate path to your project
// QQmlComponent component(engine, "MyItem.qml"); // this didn't work for me and
// set component.status() to QQmlComponent::Error
QQmlComponent component(engine, projectPath + "/qml/MyItem.qml"); // use full path
qDebug() << "Status:" << component.status();
if (component.status() == QQmlComponent::Error)
qDebug() << "Errors:" << component.errors();
else if (component.status() != QQmlComponent::Ready)
{
qDebug() << "Component is not ready!";
return 0;
}
QObject *object = component.create();
if (!object) { qDebug() << "Object creation failed!"; return 0; }
QQuickItem *item = qobject_cast<QQuickItem*>(object); // adding this didn't change much
// but this could be crucial
QVariant returnedValue;
QVariant msg = "Hello from C++";
bool success = QMetaObject::invokeMethod(item, "myQmlFunction", // replace `object` with `item`
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));
if (success)
qDebug() << "QML function returned:" << returnedValue.toString();
else
qDebug() << "QMetaObject::invokeMethod returned false";
delete object;
return 0;
}
输出
我在成功构建和成功创建对象时收到的输出是
Status: QQmlComponent::Status(Ready)
Object: MyItem_QMLTYPE_0(0x7f8d4ae8b640)
qml: Got message: Hello from C++
QML function returned: "some return value"
我还没有检查你的 Qml textbox 中的文本是否发生了变化。 (没有打扰。它需要对 C++ 代码进行更多更改,而且这个答案已经足够长了。我也确信不会出错,所以¯\_(ツ)_/¯)。
Lé 非代码
如果我不想使用原始文件路径怎么办?
如果您meh在
中使用原始文件路径(例如
/Users/whoami/ugly/looking/path)
QString projectPath = "/Users/user/full/path/to/your/project";
您可以将其添加到您的 .pro 文件中:
DEFINES += SOURCE_PATH=$$PWD
并将projectPath 设置为
QString projectPath = QT_STRINGIFY(SOURCE_PATH);
这个想法是从forum thread借来的。
假设
在我的回答中,我假设您的项目层次结构类似于
/./
|- myProject.pro
|- main.cpp
|- qml/
|- MyItem.qml
最重要的是您使用 qml 项目的完整路径。如果您确实找到另一个来引用它(也许使用QUrl?)然后做发表评论。
进一步阅读
查看QQmlComponent 类的details section 和QQmlComponent::create member function。阅读这些让我知道要调试哪些值以及要注意什么。