When a widget A is composed of multiple nested widgets, and it is the proxy widget of a widget B, the tab order cannot be changed.
Here is a test case to illustrate the problem:
#include <QtTest/QtTest>
#include <QSpinBox>
#include <QVBoxLayout>
#include <QWidget>
class FriendlyWidget : public QWidget
{ friend class Test; }
;
class Container: public QWidget {
public:
Container(QWidget* parent = 0): QWidget(parent)
{
QVBoxLayout* layout = new QVBoxLayout(this);
QSpinBox* spinbox = new QSpinBox(this);
layout->addWidget(spinbox);
setFocusProxy(spinbox);
setFocusPolicy(Qt::TabFocus);
}
};
class Test : public QObject{
Q_OBJECT
private slots:
void testTabOrder()
{
FriendlyWidget window;
QVBoxLayout* vbox = new QVBoxLayout(&window);
Container* container1 = new Container(&window);
Container* container3 = new Container(&window);
Container* container2 = new Container(&window);
Container* container4 = new Container(&window);
vbox->addWidget(container1);
vbox->addWidget(container2);
vbox->addWidget(container3);
vbox->addWidget(container4);
QWidget::setTabOrder(container1, container2);
QWidget::setTabOrder(container2, container3);
QWidget::setTabOrder(container3, container4);
container1->setFocus(Qt::OtherFocusReason);
window.show();
QWidget *widget = QApplication::focusWidget();
QCOMPARE(widget, container1);
widget->setFocus(Qt::OtherFocusReason);
window.focusNextChild();
widget = QApplication::focusWidget();
QCOMPARE(widget, container2);
widget->setFocus(Qt::OtherFocusReason);
widget = window.nextInFocusChain();
QCOMPARE(widget, container4);
widget->setFocus(Qt::OtherFocusReason);
widget = window.nextInFocusChain();
QCOMPARE(widget, container1);
window.hide();
}
};
QTEST_MAIN(Test)
#include "test.moc"