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);
490void QAbstractButton::setText(
const QString &text)
492 Q_D(QAbstractButton);
496#ifndef QT_NO_SHORTCUT
497 QKeySequence newMnemonic = QKeySequence::mnemonic(text);
498 setShortcut(newMnemonic);
500 d->sizeHint = QSize();
503#if QT_CONFIG(accessibility)
504 QAccessibleEvent event(
this, QAccessible::NameChanged);
505 QAccessible::updateAccessibility(&event);
592void QAbstractButton::setChecked(
bool checked)
594 Q_D(QAbstractButton);
595 if (!d->checkable || d->checked == checked) {
596 if (!d->blockRefresh)
601 if (!checked && d->queryCheckedButton() ==
this) {
603#if QT_CONFIG(buttongroup)
604 if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
607 d->group->d_func()->detectCheckedButton();
609 if (d->autoExclusive)
614 QPointer<QAbstractButton> guard(
this);
616 d->checked = checked;
617 if (!d->blockRefresh)
621 if (guard && checked)
624 d->emitToggled(checked);
626#if QT_CONFIG(accessibility)
628 QAccessible::State s;
630 QAccessibleStateChangeEvent event(
this, s);
631 QAccessible::updateAccessibility(&event);
684void QAbstractButton::setAutoRepeat(
bool autoRepeat)
686 Q_D(QAbstractButton);
687 if (d->autoRepeat == autoRepeat)
689 d->autoRepeat = autoRepeat;
690 if (d->autoRepeat && d->down)
691 d->repeatTimer.start(d->autoRepeatDelay,
this);
693 d->repeatTimer.stop();
808void QAbstractButton::animateClick()
812 Q_D(QAbstractButton);
813 if (d->checkable && focusPolicy() & Qt::ClickFocus)
817 if (!d->animateTimer.isActive())
819 d->animateTimer.start(100,
this);
901bool QAbstractButton::event(QEvent *e)
907 case QEvent::TabletPress:
908 case QEvent::TabletRelease:
909 case QEvent::TabletMove:
910 case QEvent::MouseButtonPress:
911 case QEvent::MouseButtonRelease:
912 case QEvent::MouseButtonDblClick:
913 case QEvent::MouseMove:
914 case QEvent::HoverMove:
915 case QEvent::HoverEnter:
916 case QEvent::HoverLeave:
917 case QEvent::ContextMenu:
924#ifndef QT_NO_SHORTCUT
925 if (e->type() == QEvent::Shortcut) {
926 Q_D(QAbstractButton);
927 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
928 if (d->shortcutId != se->shortcutId())
930 if (!se->isAmbiguous()) {
931 if (!d->animateTimer.isActive())
934 if (focusPolicy() != Qt::NoFocus)
935 setFocus(Qt::ShortcutFocusReason);
936 window()->setAttribute(Qt::WA_KeyboardFocusChange);
941 return QWidget::event(e);
1015void QAbstractButton::keyPressEvent(QKeyEvent *e)
1017 Q_D(QAbstractButton);
1020 const auto key = e->key();
1021 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1022 ->themeHint(QPlatformTheme::ButtonPressKeys)
1023 .value<QList<Qt::Key>>();
1024 if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
1037 case Qt::Key_Down: {
1038#ifdef QT_KEYPAD_NAVIGATION
1039 if ((QApplicationPrivate::keypadNavigationEnabled()
1040 && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
1041 || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
1042 || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
1047 QWidget *pw = parentWidget();
1048 if (d->autoExclusive
1049#if QT_CONFIG(buttongroup)
1052#if QT_CONFIG(itemviews)
1053 || (pw && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
1060 d->moveFocus(e->key());
1065 QWidget *w = pw ? pw :
this;
1066 bool reverse = (w->layoutDirection() == Qt::RightToLeft);
1067 if ((e->key() == Qt::Key_Left && !reverse)
1068 || (e->key() == Qt::Key_Right && reverse)) {
1071 focusNextPrevChild(next);
1076#ifndef QT_NO_SHORTCUT
1077 if (e->matches(QKeySequence::Cancel) && d->down) {
1089void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
1091 Q_D(QAbstractButton);
1093 if (!e->isAutoRepeat())
1094 d->repeatTimer.stop();
1096 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1097 ->themeHint(QPlatformTheme::ButtonPressKeys)
1098 .value<QList<Qt::Key>>();
1099 if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
1109void QAbstractButton::timerEvent(QTimerEvent *e)
1111 Q_D(QAbstractButton);
1112 if (e->timerId() == d->repeatTimer.timerId()) {
1113 d->repeatTimer.start(d->autoRepeatInterval,
this);
1115 QPointer<QAbstractButton> guard(
this);
1124 }
else if (e->timerId() == d->animateTimer.timerId()) {
1125 d->animateTimer.stop();