QML实例化C ++对象。我如何访问他们的方法?

问题描述 投票:1回答:1

这是我的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

如何从对象QQuickView view访问此C ++方法?例如,我想做一些类型view.MyClassInstance.myMethod1()

c++ qt qt5 qtquick2
1个回答
2
投票

你想获得一个用C ++在QML中创建的对象,这里目标是否有用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存在依赖关系,因为如果在QML中更改了objectName,则必须更改C ++中的代码。


另一种方法是创建一个辅助类,使用setContextProperty()将其导出到QML,并与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。

© www.soinside.com 2019 - 2024. All rights reserved.