the program crashes when calling QQuickItem::childItems()
-
Hi !
One of my methods creates a Qlist<QQuickItems*> using childItems() but when I reach this point, the program crashes.
void PresetModel::setPresetBase(void) { TRACE_DEBUG("PresetModel::setPresetBase") QQuickItem* w_object = mp_view->rootObject(); printf("\t1\n"); QList<QQuickItem*> w_items = w_object->childItems(); printf("\t2\n"); QVector<QVariant> parameters;
The program stops after 1 is printed.
Here is the test function.
void testPreset() { int carlito = 0; QGuiApplication app(carlito, nullptr); QQuickView* w_view = new QQuickView(); w_view->setSource(QUrl(QStringLiteral(QML_GENERIC_VIEW_PATH))); VIEW::PresetModel w_davey(w_view); w_davey.setPresetBase();//there is the method }
I think that's because something is wrong with the QML so the view can't access to the QQuickItems*, children of the the view's rootObject ? Do you think it's the problem ? How can I avoid it ?
-
@Quentin91 said in the program crashes when calling QQuickItem::childItems():
QQuickItem* w_object
You need to check if
w_object
isnullptr
or not and only then proceed to callchildItems()
on it.What is
mp_view
? Is it the same QQuickView you have constructed intestPreset()
? -
@Quentin91 said in the program crashes when calling QQuickItem::childItems():
I think that's because something is wrong with the QML so the view can't access to the QQuickItems*
You can check that with:
if (w_view->errors().isEmpty() == false) qDebug() << "Error!";
https://doc.qt.io/qt-5/qquickview.html#errors
Or with:
if (w_view->engine()->rootObjects().isEmpty()) qDebug() << "Error!";
-
Thank you very much for your answer @sierdzio
You need to check if w_object is nullptr
You're right, it's null
What is mp_view? Is it the same QQuickView you have constructed in testPreset()?
yes it is
The QQuickView::errors() is so usefull... Thanks a lot for that !
So now, my QML is alright but the w_object is nullBut now, Why is the QQuickItem* w_object always null ?
The QQuickView is not empty
Here is my new code :void PresetModel::setPresetBase(void) { TRACE_DEBUG("PresetModel::setPresetBase START") QQuickItem* w_object = mp_view->rootObject(); QList<QQuickItem*> w_items; if (!w_object) { TRACE_ERROR("PresetModel::setPresetBase the rootObject is null !") if (mp_view) { if (mp_view->errors().isEmpty() == false) { TRACE_ERROR("testPreset errors in da QML"); QList<QQmlError>w_errors = mp_view->errors(); cout << "xxxxxxxx QML errors xxxxxxx " << endl; for (int i = 0; i < w_errors.length(); ++i) { cout <<"\t\terror " << i<<" : ";printQStr(w_errors[i].description()) } } }//anyway w_object always null so I stop here.
The main
int carlito = 0; QGuiApplication app(carlito, nullptr); QQuickView* w_view = new QQuickView(); w_view->setSource(QUrl(QString("D:\\Users\\t0211259\\Documents\\Mes Outils Personnels\\anonymity\\TEST_VIEW4\\QML\\test2\\useless.qml"))); w_view->engine()->addImportPath(QStringLiteral("..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml")); VIEW::PresetModel w_davey(w_view); //w_davey.loadPresetFromFile(); w_davey.setPresetBase();
and the QML, just in case
import QtQuick 2.5 import QtQuick.Window 2.5 import "Items" as Items Window{ property var value: anchor.getVal(); visible: true id:mainWindow width: 150; height: 150 color: "#000000" Items.uselesItem1//this is basically a green rectangle. //Unknown component (M300)//it usually works anyway { id: johnny x: 32 y: 18 } }
-
OK so the QML shows when you run the application, right? But on C++ side
w_object
isnull
.I'm a bit confused why you set
addImportPath
after you set source. Should be the other way around. But if your code works anyway, that's probably not an issue.BTW. You don't have to escape paths like that in Qt... just use unix notation like
w_view->engine()->addImportPath(QStringLiteral("../../Tools/Qt/5.12.0/x64/5.12.0/msvc2017_64/qml"));
Hm, the problem may also be that QQuickView spawns a window. So when you pass another Window in your main QML file, the
rootObject()
gets confused - maybe. Try changingWindow
toRectangle
or a plainItem
instead. -
the QML did not show because :
you set addImportPath after you set source
That's right, and
the problem may also be that QQuickView spawns a window. So when you pass another Window in your main QML file, the rootObject() gets confused
That's absolutely right
aaand I forget the w_view.show();
So now, the QML shows but theQQuickItem* w_object = mp_view->rootObject();
is null. That's probably because my QML has no child Items for now...
Thank you very much for your help (again) @sierdzioMaybe I'll come back in this topic if the problem with rootItems is not what I think, but for now I consider the topic as solved
-
Ok, happy coding and good luck! :-)