Adding QQuickItem pointers to an std::map makes them all "not accessible" pointers or items

90 views Asked by At

This question involves Qt but could be pure C++ problem with my logic.

I am adding QQuickItems to an std::map store info about a list of QQuickItems & their respective parents.

The code:

std::array<std::string, 2> ObjectNamesArray = { "quickitemObj1", "quickitemObj2" };

std::map<QQuickItem*, QQuickItem*> items;

for(const auto& quickitem: ObjectNamesArray) {

    QQuickItem * item = Qmlengine->rootObjects()[0]->findChild<QQuickItem*>(quickitem.c_str());

    if (item != NULL)
       items.insert(std::make_pair(item, item->parent());

    // for a test, following works fine with the item pointer within this loop
    qreal width ? item->width();
}

Debugging through above loop, the items map shows zero items with the tag not accessible.

Iterating over the map again like this.

std::map<QQuickItem*, QQuickItem*>::iterator it = items.begin();
while (it != items.end()) {

    QQuickItem* item = it->first;
    QQuickItem * itemParent = it->second;  // crashes here as *item is null
    it++;
}

Problem:

But, when I try to iterate through the map, there are no valid pointers to my QQuickItems. In fact looks like there are not items added to the map.

Question:

What is wrong with my logic? How should I add QQuickItems to an std::map so that I can safely retrieve them back.

1

There are 1 answers

5
Macias On BEST ANSWER

First you have const string inside this method istead of QQuickItem name

findChild<QQuickItem*>("quickitem.c_str()");

So it gives you 0
You should add checking if item is NULL before adding to container.

Second thing is that you talking about searching items map, but here, you are appending to parents

parents.insert(std::make_pair(item, item->parent());

BTW: When you use Qt, I recommend you using Qt containers

EDIT:
This works for me, after some improvements and if i have appropriate objects in QML


CPP

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
    return -1;

std::array<std::string, 2> ObjectNamesArray = { "quickitemObj1", "quickitemObj2" };

std::map<QQuickItem*, QQuickItem*> items;

for(const auto& quickitem: ObjectNamesArray) {

    QQuickItem * item = engine.rootObjects()[0]->findChild<QQuickItem*>(quickitem.c_str());

    if (item != NULL)
       items.insert(std::make_pair(item, (QQuickItem*)item->parent()));
}

std::cout << "Map: " << items.size() << std::endl; //it gives 2

std::map<QQuickItem*, QQuickItem*>::iterator it = items.begin();
while (it != items.end()) {

    QQuickItem* item = it->first;
    QQuickItem * itemParent = it->second;  // no crash
    it++;
}

QML

import QtQuick 2.6
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Item
    {
        objectName: "quickitemObj1"
    }
    Item
    {
        objectName: "quickitemObj2"
    }
}