Эквивалент среди qml-дочерних элементов функции QObject::findChild

T QObject::findChild позволяет искать через детей определенный объект по классу и по имени:

QPushButton *button = parentWidget->findChild<QPushButton*>("button1",
                                                Qt::FindDirectChildrenOnly);

Мне нужно найти такой дочерний элемент по классу и имени. Что-то вроде

MyQQuickItem *item = parentItem->findChildItem<MyQQuickItem*>("item1");

Но функция не существует для QQuickItem,
Какой самый удобный / эффективный способ добиться этого?

До сих пор я могу думать только о петле на QQuickItem::childItems список.

1 ответ

Аналогичная логика должна быть реализована, как показано ниже:

void FindChildren_helper(const QQuickItem *parent, const QString &name, const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
{
    if (!parent || !list)
        return;
    const QList<QQuickItem *> &children = parent->childItems();
    QQuickItem *obj;
    for (int i = 0; i < children.size(); ++i) {
        obj = children.at(i);
        if(mo.cast(obj)){
            if (name.isNull() || obj->objectName() == name)
                list->append(obj);
        }
        if (options & Qt::FindChildrenRecursively)
            FindChildren_helper(obj, name, mo, list, options);
    }
}

void FindChildren_helper(const QQuickItem *parent, const QRegularExpression &re, const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
{
    if (!parent || !list)
        return;
    const QList<QQuickItem *> &children = parent->childItems();
    QQuickItem *obj;
    for (int i = 0; i < children.size(); ++i) {
        obj = children.at(i);
        if(mo.cast(obj)){
            QRegularExpressionMatch m = re.match(obj->objectName());
            if (m.hasMatch())
                list->append(obj);
        }
        if (options & Qt::FindChildrenRecursively)
            FindChildren_helper(obj, re, mo, list, options);
    }
}

template<typename T> QList<T> findChildren(QQuickItem *parent, const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively)
{
    typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
    QList<T> list;
    FindChildren_helper(parent, aName, ObjType::staticMetaObject, reinterpret_cast<QList<void *> *>(&list), options);
    return list;
}


template<typename T> QList<T> findChildren(QQuickItem *parent, const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively)
{
    typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
    QList<T> list;
    FindChildren_helper(parent, re, ObjType::staticMetaObject, reinterpret_cast<QList<void *> *>(&list), options);
    return list;
}

Пример:

QList<QQuickItem *> childs = findChildren<QQuickItem *>(parentItem, "somename", Qt::FindDirectChildrenOnly);
Другие вопросы по тегам