Код Lé
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é Non-Code
Что если я не хочу использовать необработанный путь к файлу?
Если вы 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);
Эта идея была заимствована из ветки форума .
Предположения
На протяжении всего моего ответа я предположил , чтоиерархия вашего проекта похожа на
/./
|- myProject.pro
|- main.cpp
|- qml/
|- MyItem.qml
Важно то, что вы используете свой полный путь к элементу qml.Если вы do найдете другое, чтобы сослаться на него (возможно, используя QUrl
?), Тогда do оставьте комментарий об этом.
Дополнительное чтение
Ознакомьтесь с разделом детали класса QQmlComponent
и QQmlComponent::create
функция-член .Прочитав их, я узнал, какие значения нужно отлаживать и на что обратить внимание.