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);
332 q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy,
334 q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, controlType));
335 q->setAttribute(Qt::WA_WState_OwnSizePolicy,
false);
336 q->setForegroundRole(QPalette::ButtonText);
337 q->setBackgroundRole(QPalette::Button);
493void QAbstractButton::setText(
const QString &text)
495 Q_D(QAbstractButton);
499#ifndef QT_NO_SHORTCUT
500 QKeySequence newMnemonic = QKeySequence::mnemonic(text);
501 setShortcut(newMnemonic);
503 d->sizeHint = QSize();
506#if QT_CONFIG(accessibility)
507 QAccessibleEvent event(
this, QAccessible::NameChanged);
508 QAccessible::updateAccessibility(&event);
595void QAbstractButton::setChecked(
bool checked)
597 Q_D(QAbstractButton);
598 if (!d->checkable || d->checked == checked) {
599 if (!d->blockRefresh)
604 if (!checked && d->queryCheckedButton() ==
this) {
606#if QT_CONFIG(buttongroup)
607 if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
610 d->group->d_func()->detectCheckedButton();
612 if (d->autoExclusive)
617 QPointer<QAbstractButton> guard(
this);
619 d->checked = checked;
620 if (!d->blockRefresh)
624 if (guard && checked)
627 d->emitToggled(checked);
629#if QT_CONFIG(accessibility)
631 QAccessible::State s;
633 QAccessibleStateChangeEvent event(
this, s);
634 QAccessible::updateAccessibility(&event);
687void QAbstractButton::setAutoRepeat(
bool autoRepeat)
689 Q_D(QAbstractButton);
690 if (d->autoRepeat == autoRepeat)
692 d->autoRepeat = autoRepeat;
693 if (d->autoRepeat && d->down)
694 d->repeatTimer.start(d->autoRepeatDelay,
this);
696 d->repeatTimer.stop();
811void QAbstractButton::animateClick()
815 Q_D(QAbstractButton);
816 if (d->checkable && focusPolicy() & Qt::ClickFocus)
820 if (!d->animateTimer.isActive())
822 d->animateTimer.start(100,
this);
904bool QAbstractButton::event(QEvent *e)
910 case QEvent::TabletPress:
911 case QEvent::TabletRelease:
912 case QEvent::TabletMove:
913 case QEvent::MouseButtonPress:
914 case QEvent::MouseButtonRelease:
915 case QEvent::MouseButtonDblClick:
916 case QEvent::MouseMove:
917 case QEvent::HoverMove:
918 case QEvent::HoverEnter:
919 case QEvent::HoverLeave:
920 case QEvent::ContextMenu:
927#ifndef QT_NO_SHORTCUT
928 if (e->type() == QEvent::Shortcut) {
929 Q_D(QAbstractButton);
930 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
931 if (d->shortcutId != se->shortcutId())
933 if (!se->isAmbiguous()) {
934 if (!d->animateTimer.isActive())
937 if (focusPolicy() != Qt::NoFocus)
938 setFocus(Qt::ShortcutFocusReason);
939 window()->setAttribute(Qt::WA_KeyboardFocusChange);
944 return QWidget::event(e);
1018void QAbstractButton::keyPressEvent(QKeyEvent *e)
1020 Q_D(QAbstractButton);
1023 const auto key = e->key();
1024 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1025 ->themeHint(QPlatformTheme::ButtonPressKeys)
1026 .value<QList<Qt::Key>>();
1027 if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
1040 case Qt::Key_Down: {
1041#ifdef QT_KEYPAD_NAVIGATION
1042 if ((QApplicationPrivate::keypadNavigationEnabled()
1043 && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
1044 || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
1045 || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
1050 QWidget *pw = parentWidget();
1051 if (d->autoExclusive
1052#if QT_CONFIG(buttongroup)
1055#if QT_CONFIG(itemviews)
1056 || (pw && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
1063 d->moveFocus(e->key());
1068 QWidget *w = pw ? pw :
this;
1069 bool reverse = (w->layoutDirection() == Qt::RightToLeft);
1070 if ((e->key() == Qt::Key_Left && !reverse)
1071 || (e->key() == Qt::Key_Right && reverse)) {
1074 focusNextPrevChild(next);
1079#ifndef QT_NO_SHORTCUT
1080 if (e->matches(QKeySequence::Cancel) && d->down) {
1092void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
1094 Q_D(QAbstractButton);
1096 if (!e->isAutoRepeat())
1097 d->repeatTimer.stop();
1099 const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
1100 ->themeHint(QPlatformTheme::ButtonPressKeys)
1101 .value<QList<Qt::Key>>();
1102 if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
1112void QAbstractButton::timerEvent(QTimerEvent *e)
1114 Q_D(QAbstractButton);
1115 if (e->timerId() == d->repeatTimer.timerId()) {
1116 d->repeatTimer.start(d->autoRepeatInterval,
this);
1118 QPointer<QAbstractButton> guard(
this);
1127 }
else if (e->timerId() == d->animateTimer.timerId()) {
1128 d->animateTimer.stop();