[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:
Code:
{
//version 1 -- This doesn't sort:
//QAlgorithmsPrivate::qSortHelper(..) returns immediately
//due to RandomAccessIterator end < RandomAccessIterator start
qSort(actionGroup_.actions().begin(),
actionGroup_.actions().end(),
sortOrder);
//version 2 -- "Force non-const iterator" (?)
//This enters sortOrder(..), but QAction *one and two
//are not accessible there
QList<QAction*>::iterator it1 = actionGroup_.actions().begin();
QList<QAction*>::iterator it2 = actionGroup_.actions().end();
qSort(it1,
it2,
sortOrder);
toolBar_.clear();
toolBar_.addActions(actionGroup_.actions());
return &toolBar_;
}
//Not called when trying to sort as in version 1
{
//demonstrate that one and two are not accessible in version 2
//(running into SIGSEGV)
//sorting shall be done via meta object system
bool b = //one is somehow "less than" two
return b;
}
Bad thing is, I had it running in mock code, but am not getting there again... :confused:
Thanks for you consideration!
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
Code:
QList<QAction *> tmpList = actionGroup_.actions();
qSort(tmpList.begin(), tmpList.end(), sortOrder);
toolBar_.clear();
toolBar_.addActions(tmpList);
Re: qSort() and iterator const-ness(?)
Supplement:
When I change the sorting function's signature:
Code:
//before
//after - mark the references
at least the debugger can resolve the parameters' addresses (before it would only show "<not accessible>"). However I still run into a SIGSEGV.
Re: qSort() and iterator const-ness(?)
Hi Lykurg,
Quote:
Originally Posted by
Lykurg
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
Code:
QList<QAction *> tmpList = actionGroup_.actions();
qSort(tmpList.begin(), tmpList.end(), sortOrder);
toolBar_.clear();
toolBar_.addActions(tmpList);
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.
Re: qSort() and iterator const-ness(?)
Quote:
Originally Posted by
zaphod.b
PS: How could i have found out? The
QActionGroup doc doesn't say anything about temp'ness.
Quote:
QList<QAction *> QActionGroup::actions () const
Says that it returns a list, with is not related to the internal used one by QActionGroup.
Quote:
QList<QAction *>& QActionGroup::actions () const
That would return a reference to the internal used list.
Re: qSort() and iterator const-ness(?)
Right, I was not careful enough and implicitly made assumptions that were not contracted by the interface. :(
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.
Code:
// pull out actions already in the menu
QList<QAction *> actions = menu->actions();
// re-parent to null to avoid deletion and segfault
foreach
(QAction * action, actions
) {action
->setParent
(NULL);
}
/*
* ... sort or other operations ...
*/
// clear out old actions (w/o deleting)
menu->clear();
// actions' parent is menu again
menu->addActions(actions);