Für ein Projekt muss ich QML-Komponenten zur Laufzeit aus C++ erstellen.Qt: onChildrenChanged nicht gestartet, wenn QML-Komponenten zur Laufzeit aus C++ - Code erstellt werden
Meine allgemeine Architektur ist die folgende:
Project1:
- engine.h
- Engine.cpp
- CustObject.h
- CustObject.cpp
- plugin.h
- Plugin.cpp
- Dummy.qml
Projekt2:
- main.cpp
- main.qml
Was ich tun möchte, ist Engine.cpp als Objekt QML instanziiert (möglich seit ich es in der Plugin-Klasse registriert und für Project2) verfügbar gemacht habe und dann dynamisch CustObject-Instanzen (die ebenfalls von Project2 verwendet werden) von Engine erzeugt habe. Am Ende mag ich, wenn ich schreibe:
ApplicationWindow{
id: window
visible: true
Engine{
id: eng1
CustObject{
id: custObj1
}
}
}
Das ist etwas wie das gleiche sein wird
ApplicationWindow {
id: window
visible: true
Button {
text: "add new child"
onClicked: {
console.log("QML: Number children before", eng1.children.length);
eng1.addNewChildren();
console.log("QML: Number children after", eng1.children.length);
}
}
Engine{
id: eng1
onChildrenChanged: console.log("Changed")
}
}
wie das Schreiben Und ich soll sehen, dass die Zahl der Kinder erhöht und onChildrenChanged von eng1 sein sollte gestartet.
Das Problem ist, dass weder die Anzahl der Kinder inkrementiert noch das Signal onChildrenChanged gestartet wird.
ich auch das andere Problem hatte, dass, um ein Kind den Elternteil, eng1 in meinem Fall an, ich die Funktion QQmlComponent verwendet (QQmlEngine * Motor, const QUrl & url, QObject * parent = 0) von QQMLComponent Klasse . Aber ich kann keinen Weg finden, meine CustObject-Klasse in eine QUrl umzuwandeln, da es keine .qml-Datei ist.
Daher habe ich zuerst versucht, ein Dummy-qml-Objekt namens: Dummy.qml anstelle von CustObject-Objekt hinzuzufügen. Dummy.qml sieht wie folgt aus:
engine.h:
#ifndef ENGINE_H
#define ENGINE_H
#include <QQuickItem>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQmlContext>
class Engine : public QQuickItem{
Q_OBJECT
public:
explicit Engine(QQuickItem* parent = 0);
virtual ~Engine();
Q_INVOKABLE QObject* addNewChildren();
};
#endif // ENGINE_H
Engine.cpp:
#include "Engine.h"
Engine::Engine(QQuickItem* parent) :
QQuickItem(parent)
{
}
Engine::~Engine(){ }
QObject* Engine::addNewChildren(){
qDebug() << "CPP: Number children before " << this->children().size();
QObject* parentEntity = this;
QQmlComponent* childrenEntity;
QQmlComponent component(qmlEngine(this), QUrl("qrc:///src/Dummy.qml"));
QQuickItem *childrenItem = qobject_cast<QQuickItem*>(component.create());
QQmlEngine::setObjectOwnership(childrenItem, QQmlEngine::CppOwnership);
childrenItem->setParent(parentEntity);
childrenItem->setProperty("nb", 2);
qDebug() << "CPP: Number children after" << this->children().size();
//qDebug() << "Property value:" << QQmlProperty::read(childrenItem, "nb").toInt();
return childrenItem;
}
import QtQuick 2.0
Item {
property int nb: 1
}
Der Code meiner Motor Klasse sieht wie folgt aus Aber meine Ausgabe wenn ich main führe.qml ist die folgende:
qml: QML: Number children before 0
CPP: Number children before 0
CPP: Number children after 1
qml: QML: Number children after 0
Und ich kommentierte die Linie zu QQmlProperty entsprechenden :: lesen aufgrund der folgenden Fehler: „unvollständigen Typ‚QQmlProperty‘verwendet in verschachtelten name-Bezeichner qDebug() < <“ Wert der Immobilie: "< < QQmlProperty :: lesen (childrenItem," nb "). ToInt();" ^
Ich habe daher die folgenden Fragen:
- Warum ist die Zahl der Kinder Inkrementierung nicht von qml gesehen (aber sichtbar von CPP)?
- Warum wird onChildrenChanged nicht von qml gestartet?
- Wie kann ich dynamisch hinzufügen CustObject-Klasse (die als qml-Objekt aus Sicht von Project2 sichtbar ist, seit es registriert ist) anstelle von Dummy.qml?
- Wie liest man eine Eigenschaft eines dynamisch hinzugefügten Objekts in C++ direkt nach seiner Erstellung (d. H. Wie wird QQMlProperty :: read verwendet)?
Vielen Dank im Voraus für jede Hilfe, die Sie mir geben könnten!
Dies ist ein privates Signal, das Sie nicht verwenden sollten. – dtech
Vielen Dank für Ihre schnelle Antwort! Welches Signal sollte ich dann verwenden, wenn ein Kind zu meiner Engine hinzugefügt wird? Und haben Sie irgendwelche Ideen, warum meine Kinder Variable nicht von Qt Sichtpunkt aktualisiert wird, sondern von C++ ein Ja? – tearoomFlow
Die Interna von Qt sind eher statisch und unflexibel, Sie haben nicht wirklich die Möglichkeit, sie zu ändern oder anzuzapfen. Du könntest es überschreiben, aber wer weiß, was du kaputt machen kannst, alles in allem ist es nicht schön. Eine bessere Strategie besteht darin, Ihr Design so zu ändern, dass es die Einschränkungen von Qt umgeht. Verfügen Sie über eine eigene benutzerdefinierte Funktion zum Erstellen von Objekten und zum Aussenden Ihres benutzerdefinierten Signals, um darüber zu informieren. – dtech