繁体   English   中英

将对象从QML传递到C ++

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

我正在开发一个简单的应用程序来演示C ++与QML的集成,但我遇到了问题。 简而言之,我想在qml中创建一个C ++对象,并将其传递给C ++进行处理。 这是我的代码。

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

#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

现在当我将addStudent()到学校课堂时,就会遇到麻烦。 关注.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
}

问题也在代码内的注释中,但总结如下:

  1. 当我尝试访问student.name时,为什么addStudent()会崩溃? 我设置后,我可以在qml文件中访问它。

  2. 如果我按照代码中的值传递Student ,为什么我的项目不能编译?

额外的想法

看起来它可能与C ++对象被C ++函数执行时被破坏有关。 在QML中创建的C ++对象的生命周期是什么? 什么时候被摧毁? 这个对象的生命周期可能会成为一个问题吗?

假设您通过cpp文件中的qmlRegisterTypeStudent类型注册到QML。

在QML中, Qt.createComponent("Student")不会创建Student对象而是创建QQmlComponent 尝试设置name以外的属性,它仍然有效,因为该对象不是 Student 相反,您应该通过Component.createObject从预定义的组件创建一个对象:

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

    Component {
        id: studentComponent
        Student{}
    }
}

现在一切正常。


回到你的代码,

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

不,这不好。 student.abcdefg = "Hello from QML"也有效。 添加console.log(student) ,您可以看到该student不是Student

当我尝试访问student.name时,为什么addStudent()会崩溃? 我设置后,我可以在qml文件中访问它。

它崩溃了,因为从QML传递的对象不是指针Student QML引擎将空指针传递给此函数。 您在QML中访问的内容不是Student

如果我按照代码中的值传递Student ,为什么我的项目不能编译?

因为Student是一个QObject ,它不可复制。 改为通过指针。

在QML中创建的C ++对象的生命周期是什么? 什么时候被摧毁? 这个对象的生命周期可能会成为一个问题吗?

生命周期在QML中不是问题,因为您创建的是组件,而不是对象。 在此答案中创建Student对象时,

var student = studentComponent.createObject(mainForm);

新创建的对象将mainForm设置为父级。 在释放mainForm之前,不会删除该对象。 除非您明确删除它。

尝试将类Student的声明中的函数QString name() const的声明移到Q_PROPERTY宏之前。 或者在名称功能之前再次指定“public:”。 宏将访问说明符重置为“私有”。

暂无
暂无

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

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