[英]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
}
問題也在代碼內的注釋中,但總結如下:
當我嘗試訪問student.name時,為什么addStudent()會崩潰? 我設置后,我可以在qml文件中訪問它。
如果我按照代碼中的值傳遞Student
,為什么我的項目不能編譯?
額外的想法
看起來它可能與C ++對象被C ++函數執行時被破壞有關。 在QML中創建的C ++對象的生命周期是什么? 什么時候被摧毀? 這個對象的生命周期可能會成為一個問題嗎?
假設您通過cpp文件中的qmlRegisterType
將Student
類型注冊到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.