Вы хотите получить объект, созданный в QML с помощью C ++, здесь не имеет значения, есть ли у цели прототип, созданный в C ++, или нет.Если вы хотите этого, вы должны получить объект через findChild, поскольку все объекты, созданные в QML, имеют родственные связи с окном.
main.cpp
#include <QtQuick>
#include <QtGui>
class MyClass: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
Q_INVOKABLE void invokable(){
qDebug()<< "invokable";
}
Q_SLOT void slot(){
qDebug()<< "slot";
}
void function(){
qDebug()<< "function";
}
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
QGuiApplication app(argc, argv);
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
view.show();
if(MyClass* myclass_instance = view.findChild<MyClass *>("myclass_instance")){
myclass_instance->invokable();
myclass_instance->slot();
myclass_instance->function();
}
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import foo 1.0
Rectangle {
color: "salmon"
width: 640
height: 480
MyClass{
objectName: "myclass_instance"
}
}
Но у этого метода есть несколько недостатков, таких как управление жизненным циклом объекта QML, а не C ++, поэтому указатель может в какой-то момент указать нанезарезервированный адрес.Другим недостатком является то, что существует зависимость C ++ от QML, поскольку, если objectName изменяется в QML, код на C ++ должен быть изменен.
Другой подход заключается в создании вспомогательного класса, которыйэкспортируется в QML с setContextProperty()
и взаимодействует с объектом MyClass.
main.cpp
#include <QtQuick>
#include <QtGui>
class MyClass: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
Q_INVOKABLE void invokable(){
qDebug()<< "invokable";
}
Q_SLOT void slot(){
qDebug()<< "slot";
}
void function(){
qDebug()<< "function";
}
};
class Helper: public QObject
{
Q_OBJECT
public:
using QObject::QObject;
void call_function(){
emit called();
}
Q_SIGNAL void called();
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<MyClass>("foo", 1, 0, "MyClass");
QGuiApplication app(argc, argv);
Helper helper;
QQuickView view;
view.rootContext()->setContextProperty("helper", &helper);
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
view.show();
helper.call_function();
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import foo 1.0
Rectangle {
color: "salmon"
width: 640
height: 480
MyClass{
id: myclass
}
Connections{
target: helper
onCalled:{
myclass.invokable()
myclass.slot()
}
}
}
Преимущество этого метода состоит в том, что нет никакой зависимости между логикой C ++ и QML, кроме того, жизненный цикл не создает проблем, поскольку объекты myclass не обрабатываются непосредственно в QML.Недостатком является то, что вы пишете немного больше кода и можете вызывать только Q_INVOKABLE или Q_SLOT.