1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qradiobutton.h"
5#include "qapplication.h"
6#include "qbitmap.h"
7#if QT_CONFIG(buttongroup)
8#include "qbuttongroup.h"
9#endif
10#include "qstylepainter.h"
11#include "qstyle.h"
12#include "qstyleoption.h"
13#include "qevent.h"
14
15#include "private/qabstractbutton_p.h"
16
17QT_BEGIN_NAMESPACE
18
19class QRadioButtonPrivate : public QAbstractButtonPrivate
20{
21 Q_DECLARE_PUBLIC(QRadioButton)
22
23public:
24 QRadioButtonPrivate() : QAbstractButtonPrivate(QSizePolicy::RadioButton), hovering(true) {}
25 void init();
26 uint hovering : 1;
27};
28
29/*
30 Initializes the radio button.
31*/
32void QRadioButtonPrivate::init()
33{
34 Q_Q(QRadioButton);
35 q->setCheckable(true);
36 q->setAutoExclusive(true);
37 q->setMouseTracking(true);
38 q->setForegroundRole(QPalette::WindowText);
39 q->setAttribute(Qt::WA_MacShowFocusRect);
40 setLayoutItemMargins(element: QStyle::SE_RadioButtonLayoutItem);
41}
42
43/*!
44 \class QRadioButton
45 \brief The QRadioButton widget provides a radio button with a text label.
46
47 \ingroup basicwidgets
48 \inmodule QtWidgets
49
50 \image windows-radiobutton.png
51
52 A QRadioButton is an option button that can be switched on (checked) or
53 off (unchecked). Radio buttons typically present the user with a "one
54 of many" choice. In a group of radio buttons, only one radio button at
55 a time can be checked; if the user selects another button, the
56 previously selected button is switched off.
57
58 Radio buttons are autoExclusive by default. If auto-exclusive is
59 enabled, radio buttons that belong to the same parent widget
60 behave as if they were part of the same exclusive button group. If
61 you need multiple exclusive button groups for radio buttons that
62 belong to the same parent widget, put them into a QButtonGroup.
63
64 Whenever a button is switched on or off, it emits the toggled() signal.
65 Connect to this signal if you want to trigger an action each time the
66 button changes state. Use isChecked() to see if a particular button is
67 selected.
68
69 Just like QPushButton, a radio button displays text, and
70 optionally a small icon. The icon is set with setIcon(). The text
71 can be set in the constructor or with setText(). A shortcut key
72 can be specified by preceding the preferred character with an
73 ampersand in the text. For example:
74
75 \snippet code/src_gui_widgets_qradiobutton.cpp 0
76
77 In this example the shortcut is \e{Alt+c}. See the \l
78 {QShortcut#mnemonic}{QShortcut} documentation for details. To
79 display an actual ampersand, use '&&'.
80
81 Important inherited members: text(), setText(), text(),
82 setDown(), isDown(), autoRepeat(), group(), setAutoRepeat(),
83 toggle(), pressed(), released(), clicked(), and toggled().
84
85 \sa QPushButton, QToolButton, QCheckBox, {Group Box Example}
86*/
87
88
89/*!
90 Constructs a radio button with the given \a parent, but with no text or
91 pixmap.
92
93 The \a parent argument is passed on to the QAbstractButton constructor.
94*/
95
96QRadioButton::QRadioButton(QWidget *parent)
97 : QAbstractButton(*new QRadioButtonPrivate, parent)
98{
99 Q_D(QRadioButton);
100 d->init();
101}
102
103/*!
104 Destructor.
105*/
106QRadioButton::~QRadioButton()
107{
108}
109
110/*!
111 Constructs a radio button with the given \a parent and \a text string.
112
113 The \a parent argument is passed on to the QAbstractButton constructor.
114*/
115
116QRadioButton::QRadioButton(const QString &text, QWidget *parent)
117 : QRadioButton(parent)
118{
119 setText(text);
120}
121
122/*!
123 Initialize \a option with the values from this QRadioButton. This method is useful
124 for subclasses when they need a QStyleOptionButton, but don't want to fill
125 in all the information themselves.
126
127 \sa QStyleOption::initFrom()
128*/
129void QRadioButton::initStyleOption(QStyleOptionButton *option) const
130{
131 if (!option)
132 return;
133 Q_D(const QRadioButton);
134 option->initFrom(w: this);
135 option->text = d->text;
136 option->icon = d->icon;
137 option->iconSize = iconSize();
138 if (d->down)
139 option->state |= QStyle::State_Sunken;
140 option->state |= (d->checked) ? QStyle::State_On : QStyle::State_Off;
141 if (testAttribute(attribute: Qt::WA_Hover) && underMouse()) {
142 option->state.setFlag(flag: QStyle::State_MouseOver, on: d->hovering);
143 }
144}
145
146/*!
147 \reimp
148*/
149QSize QRadioButton::sizeHint() const
150{
151 Q_D(const QRadioButton);
152 if (d->sizeHint.isValid())
153 return d->sizeHint;
154 ensurePolished();
155 QStyleOptionButton opt;
156 initStyleOption(option: &opt);
157 QSize sz = style()->itemTextRect(fm: fontMetrics(), r: QRect(), flags: Qt::TextShowMnemonic,
158 enabled: false, text: text()).size();
159 if (!opt.icon.isNull())
160 sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(a: sz.height(), b: opt.iconSize.height()));
161 d->sizeHint = style()->sizeFromContents(ct: QStyle::CT_RadioButton, opt: &opt, contentsSize: sz, w: this);
162 return d->sizeHint;
163}
164
165/*!
166 \reimp
167*/
168QSize QRadioButton::minimumSizeHint() const
169{
170 return sizeHint();
171}
172
173/*!
174 \reimp
175*/
176bool QRadioButton::hitButton(const QPoint &pos) const
177{
178 QStyleOptionButton opt;
179 initStyleOption(option: &opt);
180 return style()->subElementRect(subElement: QStyle::SE_RadioButtonClickRect, option: &opt, widget: this).contains(p: pos);
181}
182
183/*!
184 \reimp
185*/
186void QRadioButton::mouseMoveEvent(QMouseEvent *e)
187{
188 Q_D(QRadioButton);
189 if (testAttribute(attribute: Qt::WA_Hover)) {
190 bool hit = false;
191 if (underMouse())
192 hit = hitButton(pos: e->position().toPoint());
193
194 if (hit != d->hovering) {
195 update();
196 d->hovering = hit;
197 }
198 }
199
200 QAbstractButton::mouseMoveEvent(e);
201}
202
203/*!\reimp
204 */
205void QRadioButton::paintEvent(QPaintEvent *)
206{
207 QStylePainter p(this);
208 QStyleOptionButton opt;
209 initStyleOption(option: &opt);
210 p.drawControl(ce: QStyle::CE_RadioButton, opt);
211}
212
213/*! \reimp */
214bool QRadioButton::event(QEvent *e)
215{
216 Q_D(QRadioButton);
217 if (e->type() == QEvent::StyleChange
218#ifdef Q_OS_MAC
219 || e->type() == QEvent::MacSizeChange
220#endif
221 )
222 d->setLayoutItemMargins(element: QStyle::SE_RadioButtonLayoutItem);
223 return QAbstractButton::event(e);
224}
225
226
227QT_END_NAMESPACE
228
229#include "moc_qradiobutton.cpp"
230

source code of qtbase/src/widgets/widgets/qradiobutton.cpp