QML создает объекты C ++.Как мне получить доступ к их методам? - PullRequest
0 голосов
/ 18 февраля 2019

Вот как выглядит мой main.cpp:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);
    QCoreApplication::addLibraryPath("./");

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setSource(QUrl("qrc:/myqml.qml"));
    view.show();

    return app.exec();
}

Как видите, он создает вещи из myqml.Ну, myqml создает экземпляр класса C ++ MyClass.

Как мне получить доступ к этим методам C ++ из объекта QQuickView view?Например, я хотел бы сделать что-то типа view.MyClassInstance.myMethod1()

1 Ответ

0 голосов
/ 18 февраля 2019

Вы хотите получить объект, созданный в 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.

...