Results 1 to 3 of 3

Thread: QTreeView + QSortFilterProxyModel and Selection problems in the view

  1. #1
    Join Date
    Jul 2009
    Location
    Oulu, Finland
    Posts
    23
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Question QTreeView + QSortFilterProxyModel and Selection problems in the view

    Hello again Qt people,

    I try to keep this as short and simple as possible, but that's not guaranteed to happen

    Little bit background first, I have a model inherited from QAbstractItemModel and then I have QTreeView to show the content of the model in it (example for this have been taken from EditableTreeModel). I have made some modifications to this example to get the wanted data in the model. Also I have put the QSortFilterProxyModel wrapper around the model to get the sorting functionality working.

    So the problem:
    Everything seems fine at this point and I'm able to add items to the model and they pop up nice and clean to the QTreeView, as expected. Also to the right place according to the selected sorting.
    When I select some item from the view I'll update my main view (which is just a widget to show the selected items data in it). As far it seems to work as it should.

    Though, when I have some item selected from the view and that same item gets removed from the model I get some odd behavior. Selection is updated but it's not consistent which of the remaining item gets selected and what is even odder, the main view can be updated with different items data than which got selected. Usually the selection and main views content is updated correctly... but it seems that if the removed item is the first child of the root item, the selection and main view doesn't get updated correctly. In my model I just have the dummy root item which represents the header and it can have child items, but these root item's children don't have any children of their own, at least just now.

    So the tree structure in model could look something like this:

    Root Item (representing the header)
    |--- Child1
    |--- Child2
    |--- Child3

    Is there some possibility that the model indexes don't get updated correctly? Any other suggestions?

    I won't post any code just yet, but if you guys could point out the direction to look the bug for, I could probably post some specific parts of the code.

    -Tepi

  2. #2
    Join Date
    Jul 2009
    Location
    Oulu, Finland
    Posts
    23
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QTreeView + QSortFilterProxyModel and Selection problems in the view

    Here's also some code which could be part of the problem

    Code for setting the view to use the model and creating QSortFilterProxyModel wrapper around the model:
    Qt Code:
    1. void MainWindow::setServiceModel(ServiceModel *model)
    2. {
    3. treeModel = model;
    4.  
    5. // Create proxyModel and set it's properties
    6. proxyModel = new QSortFilterProxyModel(this);
    7. proxyModel->setDynamicSortFilter(true);
    8. proxyModel->setFilterKeyColumn(0);
    9. proxyModel->setSourceModel(treeModel);
    10.  
    11. serviceTree->setAlternatingRowColors(true);
    12. serviceTree->setModel(proxyModel);
    13. //serviceTree->header()->setStretchLastSection(true);
    14. serviceTree->setSortingEnabled(true);
    15. //proxyModel->sort(0, Qt::AscendingOrder);
    16.  
    17. connect(serviceTree->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
    18. this, SLOT(handleSelections(const QItemSelection &, const QItemSelection &)));
    19. }
    To copy to clipboard, switch view to plain text mode 

    And the handleSelections slot which is connected to the selectionChanged signal from the selectionModel
    Qt Code:
    1. void MainWindow::handleSelections(const QItemSelection &selected, const QItemSelection &deselected)
    2. {
    3. QModelIndexList indexes = selected.indexes();
    4. QModelIndex index, i;
    5. int row = -1;
    6. ServiceItem *service = 0;
    7.  
    8. // Go through all the selected items
    9. foreach (index, indexes) {
    10. row = proxyModel->mapToSource(index).row();
    11. i = treeModel->index(row, 0, QModelIndex());
    12. service = static_cast<ServiceItem *>(i.internalPointer());
    13.  
    14. // Do something with the selected service
    15. // This code should be rewritten if we decide to support multiple selections
    16. // Foreach-loop is already supporting multiple selections
    17. if(service)
    18. {
    19. statusBar()->showMessage(tr("Selected service: %1").arg(service->getServiceName()));
    20. serviceInfoWidget->setCurrentServiceItem(service);
    21. }
    22. else
    23. {
    24. serviceInfoWidget->clearServiceInfo();
    25. }
    26. }
    27. //}
    28.  
    29. // If none of the services in the tree is selected then clear the ServiceInfoWidgets content
    30. if(indexes.isEmpty())
    31. serviceInfoWidget->clearServiceInfo();
    32. }
    To copy to clipboard, switch view to plain text mode 

    This one is the remove method from the model code
    Qt Code:
    1. bool ServiceModel::removeService(ServiceItem *service)
    2. {
    3. bool success = false;
    4.  
    5. beginRemoveRows(QModelIndex(), service->childNumber(), service->childNumber());
    6. success = rootItem->removeChildren(service);
    7.  
    8. // If removing the service is successful then remove the service's name from the name list
    9. if(success)
    10. serviceNames.removeOne(service->getServiceName());
    11.  
    12. endRemoveRows();
    13.  
    14. return success;
    15. }
    To copy to clipboard, switch view to plain text mode 

    Don't know if these help but maybe someone can spot some mistakes here... or then it's related to some other things

    If you have some assumptions for which functions (also another functions which aren't posted in this post) the problem might be relating, just point it out and I'll check if I can post that code in here

  3. #3
    Join Date
    Jul 2009
    Location
    Oulu, Finland
    Posts
    23
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QTreeView + QSortFilterProxyModel and Selection problems in the view

    Ok, I think i figured out the source of my problem...

    I was updating the models content (by creating new items in it) in another thread and now it seems that when I do the adding in the same thread as where the model was created the model and the view are working as expected. I guess the problem is that the items live in the another thread than the model... am I on the right track here?

    Is there a safe way to modify the models content or create new items for it in another thread? For now I'll leave the implementation as it is, at least it's working now.

    This one was a quite nasty bug to find since in most cases it looked like it was working properly and because of that I wasn't suspecting the threading to cause the problem. So, word of warning to all who are doing same kind of things with threads

    Any suggestions are appreciated

    -Tepi
    Last edited by Tepi; 10th May 2010 at 13:38. Reason: updated contents

Similar Threads

  1. Replies: 1
    Last Post: 18th November 2009, 23:21
  2. QSortFilterProxyModel and QTreeView
    By PrimeCP in forum Qt Programming
    Replies: 2
    Last Post: 17th April 2009, 10:50
  3. QTreeView, QSortFilterProxyModel and item expansions
    By benacler in forum Qt Programming
    Replies: 3
    Last Post: 21st May 2008, 20:30
  4. QSortFilterProxyModel signal and selection confusion
    By pascal123 in forum Qt Programming
    Replies: 1
    Last Post: 1st April 2006, 16:25
  5. QSortFilterProxyModel & QTreeView
    By Bear in forum Qt Programming
    Replies: 3
    Last Post: 31st January 2006, 15:04

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.