Results 1 to 16 of 16

Thread: selecting lots of treewidget itemns slow ...

  1. #1
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default selecting lots of treewidget itemns slow ...

    hi,

    i have a QTreeWidget which shows the hierachy of a model. this model
    has lots of items (>10000). the items can be selected in the tree widget and
    in a 3D OpenGL view. when an item is selected in the 3D view the associated
    treewidget item should be selected as well. this is done by reacting on a signal
    and calling setItemSelected of the tree widget. well since selecting of items
    by itself is quiet ok it gets really slow when i call setItemSelected.
    how can i speed up selecting/deselecting of items in a qtreewidget?

    i used the abstractview class before but found it too complicated, so i
    would like to stay with QTreeWidget.

    best regards,
    jh

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: selecting lots of treewidget itemns slow ...

    How do you find the appropriate item to be selected?

    If you are setting many items selected/deselected in a loop, you can temporarily disable updates during the loop (see QWidget::setUpdatesEnabled(bool)) so the treewidget won't update it's contents after every single selection change.
    J-P Nurmi

  3. #3
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    i have a qhash which stores the model item as a key and the treewidget item
    as a value.

    updates disabled did not help, even if the items to be selected are
    not shown (parent collapsed) it does take a long time to call setItemSelected for
    2500 items.

    selecting the item by clicking (select the first, scroll to the end of the list,
    press shift and select the last item) takes only some msecs, but calling
    setItemSelected does take seconds!

    jh

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: selecting lots of treewidget itemns slow ...

    Can we see the code?

  5. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    Qt Code:
    1. // this method is connected to a signal which indicates that an opengl item
    2. // has been changed
    3. void Container_Widget::openglitem_changed(void* item)
    4. {
    5.  
    6. if( !isVisible() ) {
    7. return;
    8. }
    9.  
    10. // if no opengl painter, do nothing
    11. if(!_painter) return;
    12.  
    13. // cast void ptr to an opengl item
    14. mesh3D::OpenGL_ListItem* opengl_item =
    15. static_cast<mesh3D::OpenGL_ListItem*>(item);
    16.  
    17. // get a list which contains all treewidget items which are associated
    18. // to the opengl item, the list is the value of a qhash, key is the
    19.  
    20. const QList<Container_TreeWidgetItem*>* list =
    21. Container_TreeWidgetItem::items(opengl_item->element());
    22.  
    23. if(list == 0) return;
    24.  
    25. treeWidget->blockSignals(true);
    26. // treeWidget->setUpdatesEnabled(false);
    27.  
    28. for(int i=0; i<list->count(); i++) {
    29.  
    30. // printf("[%d/%d] check treewidgetitem ... \n", i, list.count());
    31.  
    32. if(treeWidget->isItemSelected((*list)[i]) != opengl_item->selected()) {
    33.  
    34. // printf("[%d] change treewidgetitem ... \n", i);
    35.  
    36. // treeWidget->setItemSelected((*list)[i], opengl_item->selected());
    37.  
    38. }
    39.  
    40. }
    41.  
    42. // treeWidget->setUpdatesEnabled(true);
    43. treeWidget->blockSignals(false);
    44.  
    45. #ifdef DEBUG_mesh3D_gui_Container_Widget
    46. printf("</Container_Widget::openglitem_changed()>\n");
    47. fflush(stdout);
    48. #endif
    49.  
    50. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 15th June 2006 at 20:23.

  6. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    sorry, have not been finished commenting the code.


    Qt Code:
    1. // this method is connected to a signal which indicates that an opengl item
    2. // has been changed
    3.  
    4. void Container_Widget:openglitem_changed(void* item)
    5. {
    6.  
    7. if( !isVisible() ) {
    8. return;
    9. }
    10.  
    11. // if no opengl painter, do nothing
    12. if(!_painter) return;
    13.  
    14. // cast void ptr to an opengl item
    15. mesh3D::OpenGL_ListItem* opengl_item =
    16. static_cast<mesh3D::OpenGL_ListItem*>(item);
    17.  
    18. // get a list which contains all treewidget items which are associated
    19. // to the opengl item, the list is the value of a qhash, key is the
    20.  
    21. const QList<Container_TreeWidgetItem*>* list =
    22. Container_TreeWidgetItem::items(opengl_item->element());
    23.  
    24. if(list == 0) return;
    25.  
    26. treeWidget->blockSignals(true);
    27. // treeWidget->setUpdatesEnabled(false);
    28.  
    29. for(int i=0; i<list->count(); i++) {
    30. treeWidget->setItemSelected((*list)[i], opengl_item->selected());
    31. }
    32.  
    33. // treeWidget->setUpdatesEnabled(true);
    34. treeWidget->blockSignals(false);
    35.  
    36.  
    37. }
    To copy to clipboard, switch view to plain text mode 



    this method is called for each changed item, which can be some thousand
    times. as long as setItemSelected is commented out it's ok, calling setitemseleced
    slows it dramatically down.

    jh
    Last edited by wysota; 15th June 2006 at 20:23.

  7. #7
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    since i still i haven't found the problem, i wrote a small test program.
    here's a screenshot:


    it just creates 1000 items with 100 sub items each. if you select some
    items and click on push button 'select children' the sub items get selected
    by iterating over the children and call setItemSelect for each one.
    for 100 items it takes 300msec on a Pentium M 1,8 GhZ !!! expanding items and
    selecting them using the mouse is much faster !?

    you can download the testprogram with an qmake project and makefiles
    here: http://www.pamidion.de/treewidgettest.zip

    any hints or any other way to select items in a qtreewidget ?

    best regards,
    jh

  8. #8
    Join Date
    Apr 2006
    Location
    San Francisco, CA
    Posts
    186
    Thanks
    55
    Thanked 12 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Red face Re: selecting lots of treewidget itemns slow ...

    Maybe you can run a profiler to see what is really taking the most time inside of setItemSelected(). It seems like you are really pushing Qt to its limits though!
    Though, there is probably something about selecting a range of indexes in QItemSelection, QItemSelectionRange... I'm not sure how it quite works though, it probably operates similar to how you manually select the indexes with the mouse.
    Last edited by gfunk; 16th June 2006 at 19:09.
    Software Engineer



  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: selecting lots of treewidget itemns slow ...

    What exactly do you want to do? IMHO your code if far from being efficient. You create and iterate over something which seems to be a quite big list. Iterating over a list which has more than 100 items is not a good idea, IMO.

  10. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    iterating over the list is not the problem, the processing of the
    method speeds up if not setItemSelected is called. in the testprogramm
    i do nothing more than traversing the children of an item
    and select one by one (the testprogram is different from the code
    i showed in the previous posting).

    in the meantime i changed the testprogram. i subclassed QTreeWidget
    to get access to the protected methods itemFromIndex and indexFromItem.
    having access to modelindexes i can assemble a QItemSelection and
    can use the selectionmodel to select items. this only takes some 10 msecs
    in the sample program instead of 300msecs. so the problem must be
    somewhere in method setItemSelected or at least in the fact that
    only one item can be selected at a time. nice side effect is that
    i get a list of selected and deselected items from the selection model.

    it would be very nice if indexFromItem/itemFromIndex were not
    protected so i do not need to subclass QTreeWidget to get
    public access to those methods.

    best regards,
    jh

    ps:
    why is iterating over a big list not a good idea? from the qt docs:

    QList uses 0-based indexes, just like C++ arrays. To access the item at a particular index position, you can use operator[](). On non-const lists, operator[]() returns a reference to the item and can be used on the left side of an assignment:

    if (list[0] == "Bob")
    list[0] = "Robert";
    Because QList is implemented as an array of pointers, this operation is very fast (constant time). For read-only access, an alternative syntax is to use at():
    Last edited by jh; 16th June 2006 at 20:19.

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: selecting lots of treewidget itemns slow ...

    There are protected because you shouldn't touch them. If you want direct access to model indexes, use QTreeView instead of QTreeWidget.

  12. #12
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    Quote Originally Posted by wysota
    There are protected because you shouldn't touch them. If you want direct access to model indexes, use QTreeView instead of QTreeWidget.
    in that case i have to implement the model as well. that is
    exactly what i wanted to avoid. the model indexes i only need because
    a selection model needs them. i would prefer to assemble a
    QItemSelection by using QTreeWidgetItems.

    jh

  13. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: selecting lots of treewidget itemns slow ...

    From what I've seen a model will only ease your job, as the "item" approach doesn't work well for complex situations (as you already discovered). Maybe you could use QStandardItemModel? Most situations can be handled by the model (or it can be subclassed and slightly changed).

  14. #14
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    the problem with the model/view classes of qt in my case is that i always
    need a row, a column and a parent. the core model (geometric elements
    which are shown in an OpenGL view), which should be shown
    also in the treeview do not store the parent of an element and since the hierachy of
    the model is determined by sets (which include elements and also sets of elements)
    the elements of the core model do not have an index. to find the row and the
    parent needed for creating a model index i had to traverse the model. this is
    to slow so i have to store a treeitem and its associated element.
    it could be easier to use persistent modelindexes but the documentation is very poor
    about the class QPersistentModelIndex so i came back to the item approach. an
    item (subclass of QTreeWidgetItem) stores the associated element , so i don't
    have to know its actual position in the model's hierachy.

    so i came to the conclusion that with the current core model i 'abuse' the
    item approach to implement an item model which stores and handles the
    row/column/parent relationships needed for a treeview.

    thanx and best regards,
    jh

  15. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: selecting lots of treewidget itemns slow ...

    Quote Originally Posted by jh
    the problem with the model/view classes of qt in my case is that i always
    need a row, a column and a parent.
    No you don't. Parent is always optional (item can have an invalid parent) and you can access an item through a pointer or a number (see internalPointer() and internalId() methods of QAbstractItemModel).

    the core model (geometric elements
    which are shown in an OpenGL view), which should be shown
    also in the treeview do not store the parent of an element and since the hierachy of
    the model is determined by sets (which include elements and also sets of elements)
    the elements of the core model do not have an index. to find the row and the
    parent needed for creating a model index i had to traverse the model. this is
    to slow so i have to store a treeitem and its associated element.
    I don't know what exactly you mean by "the core model", but IMO you should have a single model only -- the "core model" should be a subclass of QAbstractItemModel.

    it could be easier to use persistent modelindexes but the documentation is very poor
    about the class QPersistentModelIndex so i came back to the item approach. an
    item (subclass of QTreeWidgetItem) stores the associated element , so i don't
    have to know its actual position in the model's hierachy.
    Persistent indexes won't help you here.

    so i came to the conclusion that with the current core model i 'abuse' the
    item approach to implement an item model which stores and handles the
    row/column/parent relationships needed for a treeview.
    As I said -- make a single model.

  16. #16
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    84
    Thanks
    7
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: selecting lots of treewidget itemns slow ...

    Quote Originally Posted by wysota
    No you don't. Parent is always optional (item can have an invalid parent) and you can access an item through a pointer or a number (see internalPointer() and internalId() methods of QAbstractItemModel).
    if parent is invalid it means that it is a root/toplevel item. the data i want to
    show in a treeview has a hierachy but the children do not have any
    special order, i.e. the child items do not have an index (row). the itemmodel
    on the other hand, which is used to show the data in a treeview, must
    obviously have an order. otherwise items could not be shown in a widget. consequently
    i have to implement an item model which describes the hierachy (parent) and also
    the order of childitems (row). this is done for a qtreewidget (item approach) by
    trolltech anyway. so i use this one.

    Quote Originally Posted by wysota
    I don't know what exactly you mean by "the core model", but IMO you should have a single model only -- the "core model" should be a subclass of QAbstractItemModel.
    the core model has nothing to do with any qt view class. it is the model that
    describes the 'core data' of the application. in my case, the core model
    consists of surfaces/triangles/points/lines etc.

    but anyway, although i have to subclass qtreewidget to get access to
    indexFromItem and itemFromIndex Qt is still a fantastic product.

    best regards,
    jh

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.