简体   繁体   English

将对象从QML传递到C ++

[英]Passing an object from QML to C++

I am working on a simple app to demonstrate integration of C++ with QML but I have problems. 我正在开发一个简单的应用程序来演示C ++与QML的集成,但我遇到了问题。 In nutshell I want to create a C++ object in qml on fly and pass it to C++ for processing. 简而言之,我想在qml中创建一个C ++对象,并将其传递给C ++进行处理。 Here is my code. 这是我的代码。

import QtQuick 2.4
import QtQuick.Window 2.2

import test 1.0

Window {
    visible: true
    MainForm {
        anchors.fill: parent

        mouseArea.onClicked: {

            console.log("clicked")

            var student = Qt.createComponent("Student")

            student.name = "Hello frome QML";

            console.log( student.name ) // good

            school.addStudent( student )

         }
   }
}

Student.h Student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
    QString m_name;

public:
    explicit Student(QObject *parent = 0);
    ~Student();

    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

QString name() const
{
    return m_name;
}

signals:

void nameChanged(QString arg);

public slots:
void setName(QString arg)
{
    if (m_name == arg)
        return;

    m_name = arg;
    emit nameChanged(arg);
}
};

#endif // STUDENT_H

Now when I addStudent() to the school class, there is where there is trouble. 现在当我将addStudent()到学校课堂时,就会遇到麻烦。 The concern .cpp file below. 关注.cpp文件如下。

#include "school.h"
#include <QDebug>

School::School(QObject *parent) : QObject(parent)
{

}

School::~School()
{

}

// why does this not work? it cause compiler error..can't access private members of QObject
//void School::addStudent(Student student)
//{
////    students.append( &student );

////    qDebug() << "added";

////    qDebug() << student.name();// << " was added to school";
//}

void School::addStudent(Student * student)
{
    students.append( student );

    qDebug() << "added";

    qDebug() << student->name();// if this line is there, it breaks the application
}

The questions are also in comments inside the code but the summaries: 问题也在代码内的注释中,但总结如下:

  1. Why does addStudent() crashes when I try to access student.name? 当我尝试访问student.name时,为什么addStudent()会崩溃? I can access it though in the qml file after I set it. 我设置后,我可以在qml文件中访问它。

  2. Why does my project not compile if I pass Student by value like seen in the code? 如果我按照代码中的值传递Student ,为什么我的项目不能编译?

Additional thoughts 额外的想法

It seems like it may have to do with the C++ object getting destroyed by the time C++ function execute. 看起来它可能与C ++对象被C ++函数执行时被破坏有关。 What is the life cycle of C++ object created in QML? 在QML中创建的C ++对象的生命周期是什么? When does it gets destroyed? 什么时候被摧毁? Could the lifetime of the object be an issue here? 这个对象的生命周期可能会成为一个问题吗?

Assume that you register the Student type to QML via qmlRegisterType in cpp file. 假设您通过cpp文件中的qmlRegisterTypeStudent类型注册到QML。

In your QML, Qt.createComponent("Student") does not create a Student object but a QQmlComponent . 在QML中, Qt.createComponent("Student")不会创建Student对象而是创建QQmlComponent Try to set properties other than name and it still works since the object is not a Student . 尝试设置name以外的属性,它仍然有效,因为该对象不是 Student Instead, you should create an object from a pre-defined component via Component.createObject : 相反,您应该通过Component.createObject从预定义的组件创建一个对象:

MainForm {
    id: mainForm
    mouseArea.onClicked: {
        var student = studentComponent.createObject(mainForm);
        student.name = "Hello frome QML";
        school.addStudent( student );
    }

    Component {
        id: studentComponent
        Student{}
    }
}

And everything works fine now. 现在一切正常。


Back to your code, 回到你的代码,

//QML
var student = Qt.createComponent("Student")
student.name = "Hello frome QML";
console.log( student.name ) // good

No, it's not good. 不,这不好。 student.abcdefg = "Hello from QML" works, too. student.abcdefg = "Hello from QML"也有效。 Add console.log(student) and you can see that student is not a Student . 添加console.log(student) ,您可以看到该student不是Student

Why does addStudent() crashes when I try to access student.name? 当我尝试访问student.name时,为什么addStudent()会崩溃? I can access it though in the qml file after I set it. 我设置后,我可以在qml文件中访问它。

It crashed since the object passed from QML is not a pointer Student . 它崩溃了,因为从QML传递的对象不是指针Student QML engine passes a null pointer to this function. QML引擎将空指针传递给此函数。 What you accessed in QML is not a Student . 您在QML中访问的内容不是Student

Why does my project not compile if I pass Student by value like seen in the code? 如果我按照代码中的值传递Student ,为什么我的项目不能编译?

Because Student is an QObject , which is not copyable. 因为Student是一个QObject ,它不可复制。 Pass by pointer instead. 改为通过指针。

What is the life cycle of C++ object created in QML? 在QML中创建的C ++对象的生命周期是什么? When does it gets destroyed? 什么时候被摧毁? Could the lifetime of the object be an issue here? 这个对象的生命周期可能会成为一个问题吗?

The lifetime is not a issue in your QML since what you created is a component, not an object. 生命周期在QML中不是问题,因为您创建的是组件,而不是对象。 When creating Student object in this answer, 在此答案中创建Student对象时,

var student = studentComponent.createObject(mainForm);

the newly created object sets mainForm as it's parent. 新创建的对象将mainForm设置为父级。 The object won't be deleted until mainForm is released. 在释放mainForm之前,不会删除该对象。 Except you delete it explicitly. 除非您明确删除它。

Try moving the declaration of the function QString name() const in the declaration of class Student to before the Q_PROPERTY macro. 尝试将类Student的声明中的函数QString name() const的声明移到Q_PROPERTY宏之前。 Or specify "public:" again before the name function. 或者在名称功能之前再次指定“public:”。 The macro is resetting the access specifier to "private". 宏将访问说明符重置为“私有”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM