How to have TOTAL count of all rows inside a QStandardItemModel ?



  • I have a QTreeView, and this is populate by a QStandardItemModem (herited from QAbstractItemModel).
    Then, the method member herited from it: ::rowCount() is explain in the minimal doc of Qt like this :

    "Returns the number of rows under the given parent. When the parent is valid it means that rowCount is returning the number of children of parent.

    Note: When implementing a table based model, rowCount() should return 0 when the parent is valid."

    So... is someone could give me more information than the doc aournd this rowCount() ?

    I try to have ALL the TOTAL row count of my Tree... so if i ask from the top level parent the rowCount(), i not understand if it will give me back ALL the total rows or just the first down level children of this root parent of the tree ?
    The documentation is not clear for me... lot of confusion around this.

    I would like to have ALL the TOTAL rows include ALL children levels... is rowCount() do this job ?
    and if not... wich member function could give this information ?


  • Moderators

    you are right, rowCount() only returns the count of the direct children - excluding it's grandchildren.

    In QStandardItemModel the following is not the case, but for a (custom) tree model it would be possible to load it's children delayed when needed. (see QAbstractItemModel::fetchMore())

    So a count method could look like this (delayed loading not considered):
    @
    int countRowsOfIndex( const QModelIndex & index = QModelIndex() )
    {
    int count = 0;
    const QAbstractItemModel* model = index.model();
    int rowCount = model->rowCount(index);
    count += rowCount;
    for( int r = 0; r < rowCount; ++r )
    count += countRowsOfIndex( model->index(r,0,index) );
    return count;
    }
    @



  • thanks for your answer and precision around the documentation of Qt tools/member functions.

    also, is it the only one way to read this count of all children (and "little children") from a model item ?
    Because, this technic use recursive code and increase the datas memory who allready exist the time of the recursivity. I read about design patern in pragramation (not only with C++, but in general) that this is not to much good coding. But maybe the only one way sometimes.

    I'm also surprise there is no tool (member function) implemented for provide this service easily inside Qt code.

    looks like Qt is just a kind of copy of WxWidget... but for more processor support. right ?


  • Moderators

    If there would be an API already provided by Qt i think it would pretty much look like this. When it comes to trees the most efficient way is working with recursions.

    The only thing Qt and WxWidgets have in common is that they are both cross-platform toolkits.



  • ok, i do by recursive for many thinks around trees too, because in my mind it seems to be the more easy way to concept this. I follow the search if there is an other way to do it without recursive code (maybe have... if someone know, welcome to show it).

    For what i can see, this is not (so far) the only one thing that Wx have in common with Qt (in the form... maybe not under the engine...). But maybe i'm wrong and my eyes not see good.



  • What is your problem with recursive code? It is perfectly reasonable to use in many cases, and this is one of them. As long as you're not iterating of a tree that is millions of levels deep (for which a QStandardItemModel wouldn't be a good data model anyway), I don't see a problem with using it. For any reasonable tree depth, the recursion won't be a problem for your call stack at all.

    And on the commonalities between Wx and Qt: sometimes, solving the same problem just results in a very similar solution, simply because it is the best for the problem at hand. And sometimes a developer may get inspiration from how another project solved a similar problem.



  • i read book about design patern coding in C++ who explain that it is definitly not the best choice.
    I just trust about what i learn and think about the explication give is logic too. Would you like the link of the book, the page, the name of the man write it ? maybe you can send him an email for explain him that he think wrong and write stupid thinks...

    But ok... maybe it is not true, and maybe we can not see nothing (but sure... you have the ability to see beter than me, like i tell you, i just trust some leçons around design patern).
    If you want develop the subject around this, we can do it, it is interestant subject i think and could be rich leçons for all that will read and ask them same question too. Tell me.
    Also, you are a certified Specialist here (and maybe work for Qt ?)... i'm just a newbie who try to understand really and ask question (hope this is not a problem... you talk about problem... i just talk about "best" design patern... is it a problem really ? why ?)

    For the rest... just look and see, nothing to add more than what you could (just) see about Wx and Qt story. It is not a competition, just a constatation that every body can do. But why not ? Wich could be the problem around this ?

    Thanks for your explication.



  • [quote author="jerome_isAviable?" date="1422277076"]i read book about design patern coding in C++ who explain that it is definitly not the best choice.
    I just trust about what i learn and think about the explication give is logic too. Would you like the link of the book, the page, the name of the man write it ? maybe you can send him an email for explain him that he think wrong and write stupid thinks...
    [/quote]
    A source would indeed be good, though not with the purpose of sending the author a message that he is stupid. The reason would be learn, for me, and for everyone else here. It would also allow us to examine the wording of the advise given there, to see if it actually applies to this case.

    [quote]
    Also, you are a certified Specialist here (and maybe work for Qt ?)... i'm just a newbie who try to understand really and ask question (hope this is not a problem... you talk about problem... i just talk about "best" design patern... is it a problem really ? why ?)
    [/quote]
    I am a certified specialist, but I do not work for the Qt Company (or Digia, or KDAB, or ICS or any other Qt-oriënted consultancy company). Why is that relevant?

    The reason I responded is that you have been suggested a perfectly sound solution by raven-worx, but you seem to refuse to take it because it uses recursion. I was merely pointing out that it cannot recurse deeper than the number of levels you have in your tree, and that:

    unless your recursion is very deep, it will work just fine, and

    if your recursion is very deep, you have bigger problems than this.

    [quote]
    For the rest... just look and see, nothing to add more than what you could (just) see about Wx and Qt story. It is not a competition, just a constatation that every body can do. But why not ? Wich could be the problem around this ?
    [/quote]
    Who says that there is a problem? I am just pointing out that similar problems tend to lead to similar solutions at times. You seem to be suggesting that Qt is copying Wx (which I doubt, perhaps the other way around). On the other hand: I fail to see what commonalities between Wx and Qt have to do with solving your problem at all.

    Then, if you really want to avoid a recursion, you can quite easily re-write the code to iterate over the three in a non-recursive way. It will take a bit more code, but it really isn't that hard to do.



  • The reference book is "professionnal C++".
    It tell that recursive code increase memory use and give an exemple for method resolve "factorial n". I will search the line and the page for more clarity for us.
    I point you are a certified specialist, because i'm not. And then, you are more able than me for discuss this point or show exactly if this is the best practice of C++ coding or not... but not with a beginner... maybe directly with an other specialist who think it and write about that.
    That is why this could be relevant. Also... now you are a specialist about what is stupid or not... (is this a new auto proclamation ? i joke, keep calm... i think writing is not the best communication mode for translate an idea and seems to increase susceptibility more, or become agressive formaulations by awkward form of communication... i'm really sorry about that and i don't think you are stupid... i no have this pretention).

    Also, read again my post... i just write that i use it allready (recursive form) for some other stuff and will use it as long as i not learn an other way to do it well. It is a fact. So... you think wrong (if you autorize me to tell you what i wrote and what i think... please...), i never refuse to use it, i ask if there is an other way/solution to do. This is totaly different. Why do you want to tell me something i not think and never write ? it is really strange and has no interest in this discution, sorry. You show me many time that you are more intelligent than this(ok... we are human and no one is perfect, anyway)... do it again please (to be intelligent and choose thinking good), i trust you on this way only.

    I never suggest nothing. YOU said i suggest this (that Qt would be a copy of Wx...), this is really different. What's happen with you in fact ? Why you just choose the way of thinking that i suggest something bad ? I would like you have reflexion around this way of your thinking and your impressions. You can not accuse people like that because, just, you think this people suggest something.
    That i said (and that every body can see) is that Wx and Qt, by the way of use and coding, are really close together. YOU talk about copy, not me, i never suggest this (and i really don't care about that... i have no interest of this form of thinking from long long time ago... and i have no bisness interest nor Qt or Wx company, also i have no bisness man thinking).

    But sure, i would like to grow my knows for try to contribute the way of do something for use tree easier with Qt (or other, why not ?).
    By the way, from this day, the only thinks i can do is try to understand and learn, not just follow the white line without ask myself (and other) any question around why this or is it really the way i would choose if i know more... I think ther eis not only one way of thinking or one way of doing, because there is different choices depend of the interest, but if you don't know a lot... how is it possible to make a choice ?

    But ok... now you know me better, you can wash your strange (or paranoiac) thinking, and reconsider it about: what i suggest or not and what i think about all of this. I saw you were intelligent more (and many time you help me a lot with Qt, really, i 'm happy with that), so i know you will think better next time. right ? ok thanks Andre, i like your style when you think good.

    So my question is, Andre... do you know an other way of coding for this use without recursive ? (simple question) Please, forget bad thinking and teach us.

    lot of love.



  • Let's just say we are misunderstanding each other due to English not being our native language, and leave it at that shall we?

    Now, let's try a non-recursive version then:

    @
    int countRowsOfIndex( const QModelIndex & rootIndex = QModelIndex() )
    {
    int count = 0;
    const QAbstractItemModel* model = index.model();

    if (rootIndex.rowCount() == 0)
    return 0;

    QModelIndex index = model->index(0, 0, rootIndex);
    while ( index != rootIndex) {
    count++;
    if (index.hasChildren()) {
    index = model->index(0,0,index);
    } else {
    if (model->rowCount(index.parent()) == index.row() + 1) {
    index = index.parent();
    }
    if (index != rootIndex) {
    index = model->index(index.row() +1, 0, index.parent() );
    }
    }
    }
    return count;
    }
    @

    Something like this should also work. Note: code above is not tested, just typed into the editor directly.

    The idea is that you use a modelIndex to iterate through the tree depth-first, starting with the first child of the rootIndex untill you're back at the root. As long as a node has a child, you iterate into the child. If not, you iterate over the siblings until you're out of siblings, and then back up to the parent again.

    I find the recursive version posted by above easier to understand, but the principle is much the same.

    Perhaps you could also find (or write) a generic QAbstractItemModelIterator class. That would make writing a count function trivial. A very nice version of such an iterator would of course support different policies for the iteration order: depth-first/breadth-first and variations on node first of child first.



  • thanks Andre.
    yes, the principe is the same, but i don't know the difference in the memory and process power need for the two different way of doing.
    This is what i would like to understand.

    Also, i have an other idea, but i lake of knowledge and need to confront this idea to the reality:
    My idea come from the fact that, all is data.
    Then... when a tree exist, it is just the data organisation who really change, and also an other criter who is the dependance of a row (or data) inside the tree level.
    So... there is two (or more) way of thinking:
    1 read this data like that and use it as possible (that is thje way of recursive, but also the "loop search mode").
    2 change directly the data form without any recursion or loop directly inside the data

    what is this second idea ? (this idea come from the fact i do electronic from long time, and idea come from signal/datas traitment practice in real time)
    for a concret exemple:
    this idea is to have an acces of the real data hash, put it in a file (but can do directly... here, the file is an interface for change the form) and change the form of the data directly (without analyse of the content).
    Then, you just have to keep the information of the level of each element.
    Then, quickly and without use processor power (due to the fact there is no more loop or recursivity), you transform tree data organisation to a 2 dimensions table with an "index column" who represent the like hierarchie of each row/data.
    For other datas style (Role), this has to be a table for each one directly.

    Like that, easy more to do job like count total childs of an indexed data.

    So... i don't know how to access the brut data of a model (and also.. a model from tree). If i can do it, also, i can do this job by this way.
    I think this could be a way to add a member fonction to QAbstractItemModel for be able in this tree context to do this job easy.
    I think also that this way could be the quicker way and the less expensive, for little and big data the same.

    what do you think, and how to access brut data memory of a model ?



  • a schematic exemple who could be a tree data type transformed to an other organisation of same data tree :
    { ["A", "field c2 row0", "field c3"],
    { ["B", "c2 row0", "an other one"] , ["C", "row1", "my parent is A"] },
    { ["D","c2 row1","my parent is root"] }
    }

    could be transform has:

    ["A","field c2 row0", "field c3","0",""]
    ["B","c2 row0","another one","1","0"]
    ["C", "row1","my parent is A","2","0"]
    ["D","c2 row1","my parent is root","3",""]

    and then, you increase a "static" memory, but you not use the processor and not increase the memory at time search (also, you diminue time for do the job... for big data same).

    but id on't know... i need first to see and understand the data storage around the model in Qt (and way to access it) for be sure there is something to do around this could be really usable and better for this situation of count total rows (for exemple).



  • There is no generic way to access the raw data of a generic model. A well-designed generic model is usually just an adaptor to an underlying data store. That underlying data store will have methods that suit your applications needs and uses the applications data types. If you have such a thing, by all means use it directly. Would probably be easier and faster. But even models that do store their data internally all do that differently.

    However, the question was if one could get this information from the generic QAbstractItemModel interface. You can, as you have seen from both examples. I'm not sure why you are concerned about performance of either of these, before trying them out on a large model and just doing the measurements. I don't expect a large performance hit from either method on all but the largest and/or most inefficient of models (if the index method is very slow, for instance, then sure both these counting routines would be slow as well). I expect the recursive method to be a bit faster but use slightly more stack memory, but I doubt you'll notice a significant difference. However, I did not do any measurements either.



  • yes, i'm interested about performance because my app wil have to use video acquisition (4 sources in same time to view) and recording with overlayer and data acquisition from port COM, video streaming on tcp/ip, and some other stuff in same time. Also, i'm afraid about stability and process use all in parrallel. But... maybe for nothing... i don't really know now... i will see.


  • Moderators

    [quote author="jerome_isAviable?" date="1422290978"]The reference book is "professionnal C++".
    It tell that recursive code increase memory use and give an exemple for method resolve "factorial n".[/quote]It is important to understand how and why recursive code increases memory use.

    Factorial calculations produce the worst-case scenario for recursive function calls. These calculations keep consuming stack memory and never release any of that memory until the final answer is found.

    However, counting the rows of a "regular" tree structure should not behave like this. When you finish counting the (grand)child rows for the first parent, some of your stack memory gets released before you recurse into the second parent.

    [quote author="jerome_isAviable?" date="1422437864"]But... maybe for nothing... i don't really know now... i will see.[/quote]To find out, write code that uses the recursive approach and code that uses the iterative approach. Then, compare the two and see if there are any performance differences.

    Performance is important, but remember that simple and maintainable code is also important.


Log in to reply
 

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