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

标签 c++ qt qml qt5 qtquick2

这是我的 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++在QML中创建的对象,这里目标是否有一个在C++中创建的原型(prototype)并不重要。如果你想要这个,你必须通过 findChild 获取该对象,因为 QML 中创建的所有对象都与窗口有亲属关系。

ma​​in.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"

ma​​in.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 对象交互。

ma​​in.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"

ma​​in.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。

关于c++ - QML 实例化 C++ 对象。我如何访问他们的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54739100/

相关文章:

c++ - 如何将使用#ifdef编写的支持多种平台的代码移动到库函数中?

c++ - 根据类型标志将基础转换为派生类

c++ - 在 C++ 中与 Repeater 中的委托(delegate) QML 组件交互

qt - QML:在 RadioButtonStyle 中使用 Canvas

python - 使用 Python 从 QML 中动态创建的列表访问数据

c++ - 如何在opengl中获得聚光灯?

c++ - 无法访问派生类中的基类方法

c++ - QT 选项卡小部件 - 焦点上的选项卡文本行为

qt - 动态添加 QWidgets 到 QVBoxLayout

c++ - 哪个事件属于 qt c++ 中的窗口焦点更改?