Exemple #1
0
QT_END_NAMESPACE
#endif

void tst_QMenu::focus()
{
    QMenu menu;
    menu.addAction("One");
    menu.addAction("Two");
    menu.addAction("Three");

#ifdef Q_OS_MAC
    if (!qt_tab_all_widgets())
        QSKIP("Computer is currently set up to NOT tab to all widgets,"
             " this test assumes you can tab to all widgets");
#endif

    QWidget window;
    QPushButton button("Push me", &window);
    window.show();
    qApp->setActiveWindow(&window);

    QVERIFY(button.hasFocus());
    QCOMPARE(QApplication::focusWidget(), (QWidget *)&button);
    QCOMPARE(QApplication::activeWindow(), &window);
    menu.show();
    QVERIFY(button.hasFocus());
    QCOMPARE(QApplication::focusWidget(), (QWidget *)&button);
    QCOMPARE(QApplication::activeWindow(), &window);
    menu.hide();
    QVERIFY(button.hasFocus());
    QCOMPARE(QApplication::focusWidget(), (QWidget *)&button);
    QCOMPARE(QApplication::activeWindow(), &window);
}
QWidget *QWidgetWindow::getFocusWidget(FocusWidgets fw)
{
    QWidget *tlw = m_widget;
    QWidget *w = tlw->nextInFocusChain();

    QWidget *last = tlw;

    uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;

    while (w != tlw)
    {
        if (((w->focusPolicy() & focus_flag) == focus_flag)
            && w->isVisibleTo(m_widget) && w->isEnabled())
        {
            last = w;
            if (fw == FirstFocusWidget)
                break;
        }
        w = w->nextInFocusChain();
    }

    return last;
}
QT_END_NAMESPACE


void tst_QButtonGroup::arrowKeyNavigation()
{
    if (!qt_tab_all_widgets())
        QSKIP("This test requires full keyboard control to be enabled.");

    QDialog dlg(0);
    QHBoxLayout layout(&dlg);
    QGroupBox g1("1", &dlg);
    QHBoxLayout g1layout(&g1);
    QRadioButton bt1("Radio1", &g1);
    QPushButton pb("PB", &g1);
    QLineEdit le(&g1);
    QRadioButton bt2("Radio2", &g1);
    g1layout.addWidget(&bt1);
    g1layout.addWidget(&pb);
    g1layout.addWidget(&le);
    g1layout.addWidget(&bt2);

    // create a mixed button group with radion buttons and push
    // buttons. Not very useful, but it tests borderline cases wrt
    // focus handling.
    QButtonGroup bgrp1(&g1);
    bgrp1.addButton(&bt1);
    bgrp1.addButton(&pb);
    bgrp1.addButton(&bt2);

    QGroupBox g2("2", &dlg);
    QVBoxLayout g2layout(&g2);
    // we don't need a button group here, because radio buttons are
    // auto exclusive, i.e. they group themselves in he same parent
    // widget.
    QRadioButton bt3("Radio3", &g2);
    QRadioButton bt4("Radio4", &g2);
    g2layout.addWidget(&bt3);
    g2layout.addWidget(&bt4);

    layout.addWidget(&g1);
    layout.addWidget(&g2);

    dlg.show();
    qApp->setActiveWindow(&dlg);
    QVERIFY(QTest::qWaitForWindowActive(&dlg));

    bt1.setFocus();

    QTRY_VERIFY(bt1.hasFocus());

    QTest::keyClick(&bt1, Qt::Key_Right);
    QVERIFY(pb.hasFocus());
    QTest::keyClick(&pb, Qt::Key_Right);
    QVERIFY(bt2.hasFocus());
    QTest::keyClick(&bt2, Qt::Key_Right);
    QVERIFY(bt2.hasFocus());
    QTest::keyClick(&bt2, Qt::Key_Left);
    QVERIFY(pb.hasFocus());
    QTest::keyClick(&pb, Qt::Key_Left);
    QVERIFY(bt1.hasFocus());

    QTest::keyClick(&bt1, Qt::Key_Tab);
    QVERIFY(pb.hasFocus());
    QTest::keyClick(&pb, Qt::Key_Tab);

    QVERIFY(le.hasFocus());
    QCOMPARE(le.selectedText(), le.text());
    QTest::keyClick(&le, Qt::Key_Tab);

    QVERIFY(bt2.hasFocus());
    QTest::keyClick(&bt2, Qt::Key_Tab);
    QVERIFY(bt3.hasFocus());

    QTest::keyClick(&bt3, Qt::Key_Down);
    QVERIFY(bt4.hasFocus());
    QTest::keyClick(&bt4, Qt::Key_Down);
    QVERIFY(bt4.hasFocus());

    QTest::keyClick(&bt4, Qt::Key_Up);
    QVERIFY(bt3.hasFocus());
    QTest::keyClick(&bt3, Qt::Key_Up);
    QVERIFY(bt3.hasFocus());
}
Exemple #4
0
void QAbstractButtonPrivate::moveFocus(int key)
{
    QList<QAbstractButton *> buttonList = queryButtonList();;
#ifndef QT_NO_BUTTONGROUP
    bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
#else
    bool exclusive = autoExclusive;
#endif
    QWidget *f = QApplication::focusWidget();
    QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
    if (!fb || !buttonList.contains(fb))
        return;
    
    QAbstractButton *candidate = 0;
    int bestScore = -1;
    QRect target = f->rect().translated(f->mapToGlobal(QPoint(0,0)));
    QPoint goal = target.center();
    uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;

    for (int i = 0; i < buttonList.count(); ++i) {
        QAbstractButton *button = buttonList.at(i);
        if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
            (autoExclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
            QRect buttonRect = button->rect().translated(button->mapToGlobal(QPoint(0,0)));
            QPoint p = buttonRect.center();

            //Priority to widgets that overlap on the same coordinate.
            //In that case, the distance in the direction will be used as significant score,
            //take also in account orthogonal distance in case two widget are in the same distance.
            int score;
            if ((buttonRect.x() < target.right() && target.x() < buttonRect.right())
                  && (key == Qt::Key_Up || key == Qt::Key_Down)) {
                //one item's is at the vertical of the other
                score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x());
            } else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom())
                        && (key == Qt::Key_Left || key == Qt::Key_Right) ) {
                //one item's is at the horizontal of the other
                score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y());
            } else {
                score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x());
            }

            if (score > bestScore && candidate)
                continue;

            switch(key) {
            case Qt::Key_Up:
                if (p.y() < goal.y()) {
                    candidate = button;
                    bestScore = score;
                }
                break;
            case Qt::Key_Down:
                if (p.y() > goal.y()) {
                    candidate = button;
                    bestScore = score;
                }
                break;
            case Qt::Key_Left:
                if (p.x() < goal.x()) {
                    candidate = button;
                    bestScore = score;
                }
                break;
            case Qt::Key_Right:
                if (p.x() > goal.x()) {
                    candidate = button;
                    bestScore = score;
                }
                break;
            }
        }
    }

    if (exclusive
#ifdef QT_KEYPAD_NAVIGATION
        && !QApplication::keypadNavigationEnabled()
#endif
        && candidate
        && fb->d_func()->checked
        && candidate->d_func()->checkable)
        candidate->click();

    if (candidate) {
        if (key == Qt::Key_Up || key == Qt::Key_Left)
            candidate->setFocus(Qt::BacktabFocusReason);
        else
            candidate->setFocus(Qt::TabFocusReason);
    }
}