Question

I have designed a user interface by using Qt Designer, and I have set the tab order using the "edit tab order" mode.

Now what I'd like to know (for an other reason, not so important) is how to get the tab order of a specific QWidget in the ui?

I mean if I have several widgets, and say the tab order has been set, is there a way to do something like :

int nb = widget1->getTabOrder();
Was it helpful?

Solution

There is no way to get the tab order as an integer. If you look into the C++ code that the uic tool creates from your ui file, it will call QWidget::setTabOrder() a few times, and that method just takes two QWidget pointers. Thus, Qt internally doesn't even store the tab order as an integer, but rather as a chained list of QWidget pointers.

You can query that chained list with QWidget::nextInFocusChain() and QWidget::previousInFocusChain(). This gives you the whole focus chain of the widget, containing all child widgets inside it, in the right order. Then you can get the real tab order list by checking their focusPolicy, enabled state and visible state, just like the inside implementation of the QWidget::focusNextPrevChild() function. If you really need an integer index here, you need to devise an algorithm yourself that calculates indices from that obtained tab order list.

OTHER TIPS

(A bit late.) I had an a-ha moment: it's actually not at all difficult to determine the position of a widget in the tab sequence. It requires the use of Dynamic Properties, which allow you to "annotate" any QObject. The (default) focus list is simply a circular linked list with no distinguished (that I've seen identified) node. The function below annotates all the items in that linked list with a sequence number starting at the distinguished node (your choice) and provides a pointer to that in the parent widget/dialog.

Call it from your setupUi (etc.). (After any changes you may make to the focus sequence!) The parameters are the widget/dialog you want to sequence (and find the distinguished node in) and the widget you've decided should be "first" (distinguished).

// Add sequence numbers in the tab focus list starting at distinguishedNode
void sequenceFocus(QWidget *root, QWidget* distinguishedNode) 
{
    QVariant v;
    v.setValue(distinguishedNode);
    root->setProperty("focusRoot", v);

    int itemCtr = 0;
    QWidget* i = distinguishedNode;
    do {
        i->setProperty("focusPosition", itemCtr);
        i = i->nextInFocusChain();
        itemCtr++;
    } while (i != distinguishedNode);
}

You can then get the distinguished (first) item from the list from the parent with:

QWidget* start = activeDialog->property("focusRoot").value<QWidget*>();

And get the sequence position of a widget with:

my_widget->property("focusPosition").toInt()

Note that (at least) Designer ends up putting more entries in the focus list than just those marked in the focus sequence as seen in Designer. The actual focusable widgets will be sparsely numbered. (Add debugging printouts in the function above to see everything.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top