Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 ?


  • Moderators

    @Quentin91 said in the program crashes when calling QQuickItem::childItems():

    QQuickItem* w_object

    You need to check if w_object is nullptr or not and only then proceed to call childItems() on it.

    What is mp_view? Is it the same QQuickView you have constructed in testPreset()?


  • Moderators

    @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 null

    But 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
        }
    }
    

  • Moderators

    OK so the QML shows when you run the application, right? But on C++ side w_object is null.

    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 changing Window to Rectangle or a plain Item 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 the

    QQuickItem* 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) @sierdzio

    Maybe 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


  • Moderators

    Ok, happy coding and good luck! :-)


Log in to reply