Results 1 to 7 of 7

Thread: [SOLVED] qSort() and iterator const-ness(?)

  1. #1
    Join Date
    Jun 2006
    Posts
    81
    Thanks
    6
    Thanked 5 Times in 4 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Question [SOLVED] qSort() and iterator const-ness(?)

    Hi all,

    to give you an idea of what I am trying to do:
    My application loads a bunch of perspective plugins. Each perspective provides an action to activate itself. All actions are added to a QActionGroup that resides inside PerspectiveManager. Before the actions are presented in a toolbar, they need to be sorted.

    I am not able to sort the list of actions as provided by QActionGroup::actions(). So far, I tend to relate my problem to the iterator's const-ness, but I may be mistaken. Please have a look:
    Qt Code:
    1. QToolBar *PerspectiveManager::toolBar()
    2. {
    3. //version 1 -- This doesn't sort:
    4. //QAlgorithmsPrivate::qSortHelper(..) returns immediately
    5. //due to RandomAccessIterator end < RandomAccessIterator start
    6. qSort(actionGroup_.actions().begin(),
    7. actionGroup_.actions().end(),
    8. sortOrder);
    9.  
    10. //version 2 -- "Force non-const iterator" (?)
    11. //This enters sortOrder(..), but QAction *one and two
    12. //are not accessible there
    13. QList<QAction*>::iterator it1 = actionGroup_.actions().begin();
    14. QList<QAction*>::iterator it2 = actionGroup_.actions().end();
    15. qSort(it1,
    16. it2,
    17. sortOrder);
    18.  
    19. toolBar_.clear();
    20. toolBar_.addActions(actionGroup_.actions());
    21. return &toolBar_;
    22. }
    23.  
    24. //Not called when trying to sort as in version 1
    25. bool PerspectiveManager::sortOrder(QAction *one, QAction *two)
    26. {
    27. //demonstrate that one and two are not accessible in version 2
    28. //(running into SIGSEGV)
    29. QString s1(one->text());
    30. QString s2(two->text());
    31.  
    32. //sorting shall be done via meta object system
    33. bool b = //one is somehow "less than" two
    34.  
    35. return b;
    36. }
    To copy to clipboard, switch view to plain text mode 
    Bad thing is, I had it running in mock code, but am not getting there again...

    Thanks for you consideration!
    Last edited by zaphod.b; 28th July 2010 at 18:26. Reason: spelling corrections

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: qSort() and iterator const-ness(?)

    I think that actions() returns a temporary list which you sort, but when you call actions() again, the sort will be gone. So try to use
    Qt Code:
    1. QList<QAction *> tmpList = actionGroup_.actions();
    2. qSort(tmpList.begin(), tmpList.end(), sortOrder);
    3. toolBar_.clear();
    4. toolBar_.addActions(tmpList);
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to Lykurg for this useful post:

    zaphod.b (28th July 2010)

  4. #3
    Join Date
    Jun 2006
    Posts
    81
    Thanks
    6
    Thanked 5 Times in 4 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: qSort() and iterator const-ness(?)

    Supplement:

    When I change the sorting function's signature:
    Qt Code:
    1. //before
    2. bool PerspectiveManager::sortOrder(QAction *one, QAction *two)
    3. //after - mark the references
    4. bool PerspectiveManager::sortOrder(QAction *&one, QAction *&two)
    To copy to clipboard, switch view to plain text mode 
    at least the debugger can resolve the parameters' addresses (before it would only show "<not accessible>"). However I still run into a SIGSEGV.

  5. #4
    Join Date
    Jun 2006
    Posts
    81
    Thanks
    6
    Thanked 5 Times in 4 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: qSort() and iterator const-ness(?)

    Hi Lykurg,

    Quote Originally Posted by Lykurg View Post
    I think that actions() returns a temporary list which you sort, but when you call actions() again, the sort will be gone. So try to use
    Qt Code:
    1. QList<QAction *> tmpList = actionGroup_.actions();
    2. qSort(tmpList.begin(), tmpList.end(), sortOrder);
    3. toolBar_.clear();
    4. toolBar_.addActions(tmpList);
    To copy to clipboard, switch view to plain text mode 
    Perfectly right!
    Edit: Well, I don't sort this way, but this explains why begin() and end() are in wrong order or rather totally unrelated.

    Thx alot!

    PS: How could i have found out? The QActionGroup doc doesn't say anything about temp'ness.
    Last edited by zaphod.b; 28th July 2010 at 16:11.

  6. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: qSort() and iterator const-ness(?)

    Quote Originally Posted by zaphod.b View Post
    PS: How could i have found out? The QActionGroup doc doesn't say anything about temp'ness.
    QList<QAction *> QActionGroup::actions () const
    Says that it returns a list, with is not related to the internal used one by QActionGroup.
    QList<QAction *>& QActionGroup::actions () const
    That would return a reference to the internal used list.

  7. #6
    Join Date
    Jun 2006
    Posts
    81
    Thanks
    6
    Thanked 5 Times in 4 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: qSort() and iterator const-ness(?)

    Right, I was not careful enough and implicitly made assumptions that were not contracted by the interface.

  8. #7
    Join Date
    Mar 2009
    Posts
    14
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb Re: qSort() and iterator const-ness(?)

    For anyone else stumbling into this thread, you can also sort actions that are already added to a menu, but some extra care must be taken.

    The method shown in earlier posts will only work if the QActions are not owned by the QMenu you clear them from, or if they are shown in any other widget. Otherwise QMenu::clear() will delete them. So this means if you added them via QMenu::addAction() or a similar function, and don't use the action anywhere else in your application, you'll likely segfault.

    You can work around this by temporarily setting the parent of all the actions in the list to NULL.

    Qt Code:
    1. QMenu * menu;
    2.  
    3. // pull out actions already in the menu
    4. QList<QAction *> actions = menu->actions();
    5. // re-parent to null to avoid deletion and segfault
    6. foreach(QAction * action, actions) {action->setParent(NULL);}
    7.  
    8. /*
    9.  * ... sort or other operations ...
    10.  */
    11.  
    12. // clear out old actions (w/o deleting)
    13. menu->clear();
    14. // actions' parent is menu again
    15. menu->addActions(actions);
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QSort
    By skumar7777 in forum Qt Programming
    Replies: 4
    Last Post: 2nd December 2008, 06:18
  2. qSort with lessThan
    By soul_rebel in forum Qt Programming
    Replies: 4
    Last Post: 19th August 2008, 18:14
  3. const member and const method
    By mickey in forum General Programming
    Replies: 8
    Last Post: 9th April 2008, 09:44
  4. qSort() problem
    By darksaga in forum Qt Programming
    Replies: 5
    Last Post: 17th August 2007, 11:47
  5. [Qt4] QSORT
    By jane in forum Qt Programming
    Replies: 6
    Last Post: 24th May 2006, 23:38

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
  •  
Qt is a trademark of The Qt Company.