155#if QT_CONFIG(buttongroup)
157 return group->d_func()->buttonList;
162 QList<QAbstractButton *> candidates = parent->findChildren<QAbstractButton *>();
164 auto isNoMemberOfMyAutoExclusiveGroup = [](QAbstractButton *candidate) {
165 return !candidate->autoExclusive()
166#if QT_CONFIG(buttongroup)
167 || candidate->group()
171 candidates.removeIf(isNoMemberOfMyAutoExclusiveGroup);
178#if QT_CONFIG(buttongroup)
180 return group->d_func()->checkedButton;
183 Q_Q(
const QAbstractButton);
184 QList<QAbstractButton *> buttonList = queryButtonList();
185 if (!autoExclusive || buttonList.size() == 1)
188 for (
int i = 0; i < buttonList.size(); ++i) {
189 QAbstractButton *b = buttonList.at(i);
190 if (b->d_func()->checked && b != q)
193 return checked ?
const_cast<QAbstractButton *>(q) :
nullptr;
198#if QT_CONFIG(buttongroup)
199 Q_Q(QAbstractButton);
201 QAbstractButton *previous = group->d_func()->checkedButton;
202 group->d_func()->checkedButton = q;
203 if (group->d_func()->exclusive && previous && previous != q)
204 previous->nextCheckState();
208 if (QAbstractButton *b = queryCheckedButton())
209 b->setChecked(
false);
215 QList<QAbstractButton *> buttonList = queryButtonList();
216#if QT_CONFIG(buttongroup)
217 bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
219 bool exclusive = autoExclusive;
221 QWidget *f = QApplication::focusWidget();
222 QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
223 if (!fb || !buttonList.contains(fb))
226 QAbstractButton *candidate =
nullptr;
228 QRect target = f->rect().translated(f->mapToGlobal(QPoint(0,0)));
229 QPoint goal = target.center();
230 uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
232 for (
int i = 0; i < buttonList.size(); ++i) {
233 QAbstractButton *button = buttonList.at(i);
234 if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
235 (exclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
236 QRect buttonRect = button->rect().translated(button->mapToGlobal(QPoint(0,0)));
237 QPoint p = buttonRect.center();
243 if ((buttonRect.x() < target.right() && target.x() < buttonRect.right())
244 && (key == Qt::Key_Up || key == Qt::Key_Down)) {
246 score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x());
247 }
else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom())
248 && (key == Qt::Key_Left || key == Qt::Key_Right) ) {
250 score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y());
252 score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x());
255 if (score > bestScore && candidate)
260 if (p.y() < goal.y()) {
266 if (p.y() > goal.y()) {
272 if (p.x() < goal.x()) {
278 if (p.x() > goal.x()) {
288#ifdef QT_KEYPAD_NAVIGATION
289 && !QApplicationPrivate::keypadNavigationEnabled()
292 && fb->d_func()->checked
293 && candidate->d_func()->checkable)
297 if (key == Qt::Key_Up || key == Qt::Key_Left)
298 candidate->setFocus(Qt::BacktabFocusReason);
300 candidate->setFocus(Qt::TabFocusReason);
306 Q_Q(QAbstractButton);
307#if QT_CONFIG(buttongroup)
308 if (!group && !autoExclusive)
314 QList<QAbstractButton *> buttonList = queryButtonList();
315 for (
int i = 0; i < buttonList.size(); ++i) {
316 QAbstractButton *b = buttonList.at(i);
317 if (!b->isCheckable())
319 b->setFocusPolicy((Qt::FocusPolicy) ((b == q || !q->isCheckable())
320 ? (b->focusPolicy() | Qt::TabFocus)
321 : (b->focusPolicy() & ~Qt::TabFocus)));
327 Q_Q(QAbstractButton);
329 q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy,
nullptr, q)));
330 q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, controlType));
331 q->setAttribute(Qt::WA_WState_OwnSizePolicy,
false);
332 q->setForegroundRole(QPalette::ButtonText);
333 q->setBackgroundRole(QPalette::Button);
482void QAbstractButton::setText(
const QString &text)
484 Q_D(QAbstractButton);
488#ifndef QT_NO_SHORTCUT
489 QKeySequence newMnemonic = QKeySequence::mnemonic(text);
490 setShortcut(newMnemonic);
492 d->sizeHint = QSize();
495#if QT_CONFIG(accessibility)
496 QAccessibleEvent event(
this, QAccessible::NameChanged);
497 QAccessible::updateAccessibility(&event);
584void QAbstractButton::setChecked(
bool checked)
586 Q_D(QAbstractButton);
587 if (!d->checkable || d->checked == checked) {
588 if (!d->blockRefresh)
593 if (!checked && d->queryCheckedButton() ==
this) {
595#if QT_CONFIG(buttongroup)
596 if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
599 d->group->d_func()->detectCheckedButton();
601 if (d->autoExclusive)
606 QPointer<QAbstractButton> guard(
this);
608 d->checked = checked;
609 if (!d->blockRefresh)
613 if (guard && checked)
616 d->emitToggled(checked);
618#if QT_CONFIG(accessibility)
620 QAccessible::State s;
622 QAccessibleStateChangeEvent event(
this, s);
623 QAccessible::updateAccessibility(&event);
676void QAbstractButton::setAutoRepeat(
bool autoRepeat)
678 Q_D(QAbstractButton);
679 if (d->autoRepeat == autoRepeat)
681 d->autoRepeat = autoRepeat;
682 if (d->autoRepeat && d->down)
683 d->repeatTimer.start(d->autoRepeatDelay,
this);
685 d->repeatTimer.stop();
800void QAbstractButton::animateClick()
804 Q_D(QAbstractButton);
805 if (d->checkable && focusPolicy() & Qt::ClickFocus)
809 if (!d->animateTimer.isActive())
811 d->animateTimer.start(100,
this);
893bool QAbstractButton::event(QEvent *e)
899 case QEvent::TabletPress:
900 case QEvent::TabletRelease:
901 case QEvent::TabletMove:
902 case QEvent::MouseButtonPress:
903 case QEvent::MouseButtonRelease:
904 case QEvent::MouseButtonDblClick:
905 case QEvent::MouseMove:
906 case QEvent::HoverMove:
907 case QEvent::HoverEnter:
908 case QEvent::HoverLeave:
909 case QEvent::ContextMenu:
916#ifndef QT_NO_SHORTCUT
917 if (e->type() == QEvent::Shortcut) {
918 Q_D(QAbstractButton);
919 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
920 if (d->shortcutId != se->shortcutId())
922 if (!se->isAmbiguous()) {
923 if (!d->animateTimer.isActive())
926 if (focusPolicy() != Qt::NoFocus)
927 setFocus(Qt::ShortcutFocusReason);
928 window()->setAttribute(Qt::WA_KeyboardFocusChange);
933 return QWidget::event(e);
1007void QAbstractButton::keyPressEvent(QKeyEvent *e)
1009 Q_D(QAbstractButton);
1012 const auto key = e->key();
1013 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1014 ->themeHint(QPlatformTheme::ButtonPressKeys)
1015 .value<QList<Qt::Key>>();
1016 if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
1029 case Qt::Key_Down: {
1030#ifdef QT_KEYPAD_NAVIGATION
1031 if ((QApplicationPrivate::keypadNavigationEnabled()
1032 && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
1033 || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
1034 || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
1039 QWidget *pw = parentWidget();
1040 if (d->autoExclusive
1041#if QT_CONFIG(buttongroup)
1044#if QT_CONFIG(itemviews)
1045 || (pw && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
1052 d->moveFocus(e->key());
1057 QWidget *w = pw ? pw :
this;
1058 bool reverse = (w->layoutDirection() == Qt::RightToLeft);
1059 if ((e->key() == Qt::Key_Left && !reverse)
1060 || (e->key() == Qt::Key_Right && reverse)) {
1063 focusNextPrevChild(next);
1068#ifndef QT_NO_SHORTCUT
1069 if (e->matches(QKeySequence::Cancel) && d->down) {
1081void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
1083 Q_D(QAbstractButton);
1085 if (!e->isAutoRepeat())
1086 d->repeatTimer.stop();
1088 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1089 ->themeHint(QPlatformTheme::ButtonPressKeys)
1090 .value<QList<Qt::Key>>();
1091 if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
1101void QAbstractButton::timerEvent(QTimerEvent *e)
1103 Q_D(QAbstractButton);
1104 if (e->timerId() == d->repeatTimer.timerId()) {
1105 d->repeatTimer.start(d->autoRepeatInterval,
this);
1107 QPointer<QAbstractButton> guard(
this);
1116 }
else if (e->timerId() == d->animateTimer.timerId()) {
1117 d->animateTimer.stop();