156#if QT_CONFIG(buttongroup)
158 return group->d_func()->buttonList;
163 QList<QAbstractButton *> candidates = parent->findChildren<QAbstractButton *>();
165 auto isNoMemberOfMyAutoExclusiveGroup = [](QAbstractButton *candidate) {
166 return !candidate->autoExclusive()
167#if QT_CONFIG(buttongroup)
168 || candidate->group()
172 candidates.removeIf(isNoMemberOfMyAutoExclusiveGroup);
179#if QT_CONFIG(buttongroup)
181 return group->d_func()->checkedButton;
184 Q_Q(
const QAbstractButton);
185 QList<QAbstractButton *> buttonList = queryButtonList();
186 if (!autoExclusive || buttonList.size() == 1)
189 for (
int i = 0; i < buttonList.size(); ++i) {
190 QAbstractButton *b = buttonList.at(i);
191 if (b->d_func()->checked && b != q)
194 return checked ?
const_cast<QAbstractButton *>(q) :
nullptr;
199#if QT_CONFIG(buttongroup)
200 Q_Q(QAbstractButton);
202 QAbstractButton *previous = group->d_func()->checkedButton;
203 group->d_func()->checkedButton = q;
204 if (group->d_func()->exclusive && previous && previous != q)
205 previous->nextCheckState();
209 if (QAbstractButton *b = queryCheckedButton())
210 b->setChecked(
false);
216 QList<QAbstractButton *> buttonList = queryButtonList();
217#if QT_CONFIG(buttongroup)
218 bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
220 bool exclusive = autoExclusive;
222 QWidget *f = QApplication::focusWidget();
223 QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
224 if (!fb || !buttonList.contains(fb))
227 QAbstractButton *candidate =
nullptr;
229 QRect target = f->rect().translated(f->mapToGlobal(QPoint(0,0)));
230 QPoint goal = target.center();
231 uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
233 for (
int i = 0; i < buttonList.size(); ++i) {
234 QAbstractButton *button = buttonList.at(i);
235 if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
236 (exclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
237 QRect buttonRect = button->rect().translated(button->mapToGlobal(QPoint(0,0)));
238 QPoint p = buttonRect.center();
244 if ((buttonRect.x() < target.right() && target.x() < buttonRect.right())
245 && (key == Qt::Key_Up || key == Qt::Key_Down)) {
247 score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x());
248 }
else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom())
249 && (key == Qt::Key_Left || key == Qt::Key_Right) ) {
251 score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y());
253 score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x());
256 if (score > bestScore && candidate)
261 if (p.y() < goal.y()) {
267 if (p.y() > goal.y()) {
273 if (p.x() < goal.x()) {
279 if (p.x() > goal.x()) {
289#ifdef QT_KEYPAD_NAVIGATION
290 && !QApplicationPrivate::keypadNavigationEnabled()
293 && fb->d_func()->checked
294 && candidate->d_func()->checkable)
298 if (key == Qt::Key_Up || key == Qt::Key_Left)
299 candidate->setFocus(Qt::BacktabFocusReason);
301 candidate->setFocus(Qt::TabFocusReason);
307 Q_Q(QAbstractButton);
308#if QT_CONFIG(buttongroup)
309 if (!group && !autoExclusive)
315 QList<QAbstractButton *> buttonList = queryButtonList();
316 for (
int i = 0; i < buttonList.size(); ++i) {
317 QAbstractButton *b = buttonList.at(i);
318 if (!b->isCheckable())
320 b->setFocusPolicy((Qt::FocusPolicy) ((b == q || !q->isCheckable())
321 ? (b->focusPolicy() | Qt::TabFocus)
322 : (b->focusPolicy() & ~Qt::TabFocus)));
328 Q_Q(QAbstractButton);
330 q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy,
nullptr, q)));
331 q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, controlType));
332 q->setAttribute(Qt::WA_WState_OwnSizePolicy,
false);
333 q->setForegroundRole(QPalette::ButtonText);
334 q->setBackgroundRole(QPalette::Button);
483void QAbstractButton::setText(
const QString &text)
485 Q_D(QAbstractButton);
489#ifndef QT_NO_SHORTCUT
490 QKeySequence newMnemonic = QKeySequence::mnemonic(text);
491 setShortcut(newMnemonic);
493 d->sizeHint = QSize();
496#if QT_CONFIG(accessibility)
497 QAccessibleEvent event(
this, QAccessible::NameChanged);
498 QAccessible::updateAccessibility(&event);
585void QAbstractButton::setChecked(
bool checked)
587 Q_D(QAbstractButton);
588 if (!d->checkable || d->checked == checked) {
589 if (!d->blockRefresh)
594 if (!checked && d->queryCheckedButton() ==
this) {
596#if QT_CONFIG(buttongroup)
597 if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
600 d->group->d_func()->detectCheckedButton();
602 if (d->autoExclusive)
607 QPointer<QAbstractButton> guard(
this);
609 d->checked = checked;
610 if (!d->blockRefresh)
614 if (guard && checked)
617 d->emitToggled(checked);
619#if QT_CONFIG(accessibility)
621 QAccessible::State s;
623 QAccessibleStateChangeEvent event(
this, s);
624 QAccessible::updateAccessibility(&event);
677void QAbstractButton::setAutoRepeat(
bool autoRepeat)
679 Q_D(QAbstractButton);
680 if (d->autoRepeat == autoRepeat)
682 d->autoRepeat = autoRepeat;
683 if (d->autoRepeat && d->down)
684 d->repeatTimer.start(d->autoRepeatDelay,
this);
686 d->repeatTimer.stop();
801void QAbstractButton::animateClick()
805 Q_D(QAbstractButton);
806 if (d->checkable && focusPolicy() & Qt::ClickFocus)
810 if (!d->animateTimer.isActive())
812 d->animateTimer.start(100,
this);
894bool QAbstractButton::event(QEvent *e)
900 case QEvent::TabletPress:
901 case QEvent::TabletRelease:
902 case QEvent::TabletMove:
903 case QEvent::MouseButtonPress:
904 case QEvent::MouseButtonRelease:
905 case QEvent::MouseButtonDblClick:
906 case QEvent::MouseMove:
907 case QEvent::HoverMove:
908 case QEvent::HoverEnter:
909 case QEvent::HoverLeave:
910 case QEvent::ContextMenu:
917#ifndef QT_NO_SHORTCUT
918 if (e->type() == QEvent::Shortcut) {
919 Q_D(QAbstractButton);
920 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
921 if (d->shortcutId != se->shortcutId())
923 if (!se->isAmbiguous()) {
924 if (!d->animateTimer.isActive())
927 if (focusPolicy() != Qt::NoFocus)
928 setFocus(Qt::ShortcutFocusReason);
929 window()->setAttribute(Qt::WA_KeyboardFocusChange);
934 return QWidget::event(e);
1008void QAbstractButton::keyPressEvent(QKeyEvent *e)
1010 Q_D(QAbstractButton);
1013 const auto key = e->key();
1014 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1015 ->themeHint(QPlatformTheme::ButtonPressKeys)
1016 .value<QList<Qt::Key>>();
1017 if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
1030 case Qt::Key_Down: {
1031#ifdef QT_KEYPAD_NAVIGATION
1032 if ((QApplicationPrivate::keypadNavigationEnabled()
1033 && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
1034 || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
1035 || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
1040 QWidget *pw = parentWidget();
1041 if (d->autoExclusive
1042#if QT_CONFIG(buttongroup)
1045#if QT_CONFIG(itemviews)
1046 || (pw && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
1053 d->moveFocus(e->key());
1058 QWidget *w = pw ? pw :
this;
1059 bool reverse = (w->layoutDirection() == Qt::RightToLeft);
1060 if ((e->key() == Qt::Key_Left && !reverse)
1061 || (e->key() == Qt::Key_Right && reverse)) {
1064 focusNextPrevChild(next);
1069#ifndef QT_NO_SHORTCUT
1070 if (e->matches(QKeySequence::Cancel) && d->down) {
1082void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
1084 Q_D(QAbstractButton);
1086 if (!e->isAutoRepeat())
1087 d->repeatTimer.stop();
1089 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1090 ->themeHint(QPlatformTheme::ButtonPressKeys)
1091 .value<QList<Qt::Key>>();
1092 if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
1102void QAbstractButton::timerEvent(QTimerEvent *e)
1104 Q_D(QAbstractButton);
1105 if (e->timerId() == d->repeatTimer.timerId()) {
1106 d->repeatTimer.start(d->autoRepeatInterval,
this);
1108 QPointer<QAbstractButton> guard(
this);
1117 }
else if (e->timerId() == d->animateTimer.timerId()) {
1118 d->animateTimer.stop();