[SOLVED!] How to find a Child in a QAbstractItemModel



  • Hi,

    I have experimented on the editable treemodel example.
    At this time every item contains three columns, text, blocknumber, text;
    Since every blocknumber is unique, I'm trying to find the item in a QTreeView with match();

    @QModelIndexList list = model->match(model->index(0, 1), Qt::DisplayRole, QVariant::fromValue(blocknr), 1, Qt::MatchRecursive);
    @

    For some reason match() just looks at the root item not at the children.

    How do I use match the right way?



  • [quote]For some reason match() just looks at the root item not at the children.[/quote]
    Does it find anything?

    QAbstractItemModel::match() uses rowCount() and columnCount() to detect if a parent index has the children.
    @
    (rowCount(parent) > 0) && (columnCount(parent) > 0)
    @

    These functions are implemented in TreeModel.
    Could you verify if they are called?

    Another option is to use Qt::MatchExactly because your are looking through the numbers.



  • I have checked rowcount an columnscount on the parentitem.

    @QString str1;
    str1.setNum(model->rowCount(model->index(0, 1)));

    QMessageBox mb;
    mb.setText(str1);
    mb.exec();@

    and

    @QString str2;
    str2.setNum(model->columnCount(model->index(0, 1)));

    QMessageBox mb;
    mb.setText(str2);
    mb.exec();@

    rowcount gives me 6, which is correct.
    coulumncount gives me 3, which is also correct.

    Should Qt::MatchRecursive not also look at the children?



  • Qt::MatchExactly gives me the same result as Qt::MatchRecursive.



  • [quote]Should Qt::MatchRecursive not also look at the children?[/quote]
    Yes it should look at the children if current index has children.

    [quote] Qt::MatchExactly gives me the same result as Qt::MatchRecursive.[/quote]
    You need to OR them Qt::MatchExactly | Qt::MatchRecursive
    @
    QModelIndexList list = model->match(model->index(0, 1), Qt::DisplayRole, QVariant::fromValue(blocknr), 1, Qt::MatchExactly | Qt::MatchRecursive);
    @
    Qt::MatchExactly force match() to compare the number using =. Without it match() will convert the value into string an will call contains() function.

    It will not solve the recursive issue. Just premature optimization :-)



  • Thanks a lot!

    I will try it tomorrow. Now I'm going to bed, because I have to get up early for work.

    In a similar post at http://qt-project.org/forums/viewthread/4864, it seems it does work. In this post Volker asks "How do you create a hierarchy then?"

    Perhaps this could lead to an solution? Since I used an example from Qt to start with.



  • What I have found so far that TreeModel from the example does not like to create a valid index for the column other than 0.
    I think there are other bumps in that model.
    So you need to fix a TreeModel::index() function. Maybe some other too.

    [EDIT] It creates a valid children index only for first column.



  • I took just a quick look before going to work.
    I see what you mean, although i'm still learning and this part ain't the easiest.

    At first I whas thinking of taking another approach by using QStandardItemModel, but then again, it is more fun to make this work!

    It will take me some time though so thanks for now.
    I will let you now when I have solved it.



  • Oke, my problem with the match() is solved!
    I have looked at other examples and changed the index from:

    @ if (parent.isValid() && parent.column() != 0)
    return QModelIndex();

    ContentsItem *parentItem = getItem(parent);
    
    ContentsItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();@
    

    to:

    @if (!hasIndex(row, column, parent))
    return QModelIndex();

    ContentsItem *parentItem = getItem(parent);
    
    if (!parent.isValid())
        parentItem = rootItem;
    
    ContentsItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();@
    

    You mentioned that I probably would have to fix other functions too.
    I guess I will have to wait and see what I will stumble upon.
    For now the problem is solved. Thank you very much, andreyc, for your help.



  • You are welcome. Glad that it works for you.

    [quote]You mentioned that I probably would have to fix other functions too.[/quote] Looks like the fix that you did for the index function should be enough for the search.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.