'QToolbar.children() lists children in order of addition/insertion, not appearance
The QToolBar method insertWidget(QAction, QWidget) does correctly insert the widget at the intended place, but QToolBar.children() (actually QObject.children()) shows the output list of children ordered according to the order in which they were added or inserted, not in the order of their left-to-right appearance; the children() doc says that explicitly. That's probably not unreasonable, since children() is a method of QObject, and QObject knows nothing about its derived toolbar.
This may be related to a perplexing bug (IMO) in which QToolBar returns incorrect action objects on a mouse press event after an insertWidget(). I believe the system is counting the position of the clicked widget and returning its action object based on the (false) assumption that all widgets were added with addWidget(). But rather than dwell on this possible bug, my question is: is there a way to shuffle the output of children() such that it reflects the appearance of the widgets in the toolbar, rather than the order in which they were added or inserted? Brute force solutions are always possible, but I'd prefer something pythonic.
Edit:
(I think there used to be a link on this site, "answer your own question". I can't find it, so I'll post it here.)
It is not possible to shuffle the output of children() or its variants. However, a workaround is possible. The reason for wanting the toolbar items in order of appearance is so that they may be saved (e.g., in a ConfigParser file) and restored in the same order.
If any toolbar items have been added with insertWidget(), QToolbar.children() or its variants will not reflect the order of their appearance in the toolbar. IOW, code that looks like this is useless in finding widgets in toolbar order:
fieldlst = self.toolbar.findChildren(QPushButton,'', Qt.FindChildOption.FindDirectChildrenOnly)
However, a toolbar contains a layout which is implicity added and can be retrieved with QToolbar.layout(). Items can then be retrieved in the order of their appearance with code like this:
lt = self.toolbar.layout()
fieldlst = [lt.itemAt(k).widget() for k in range(lt.count())]
Cruder solutions are possible without using the layout, such as reading the enclosing rectangle of widgets returned by a children() variant, and then sorting on the coordinate of the left edge, but the solution given above seems simplest.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|