Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcheckbox.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
5#include "qcheckbox.h"
6#include "qapplication.h"
7#include "qbitmap.h"
8#include "qicon.h"
10#include "qstyle.h"
11#include "qstyleoption.h"
12#include "qevent.h"
13#if QT_CONFIG(accessibility)
14#include "qaccessible.h"
15#endif
16
17#include "private/qabstractbutton_p.h"
18
20
22{
23 Q_DECLARE_PUBLIC(QCheckBox)
24public:
28
33
34 void init();
35};
36
37/*!
38 \class QCheckBox
39 \brief The QCheckBox widget provides a checkbox with a text label.
40
41 \ingroup basicwidgets
42 \inmodule QtWidgets
43
44 \image fusion-checkbox.png {Check box for the save option}
45
46 A QCheckBox is an option button that can be switched on (checked) or off
47 (unchecked). Checkboxes are typically used to represent features in an
48 application that can be enabled or disabled without affecting others.
49 Different types of behavior can be implemented. For example, a
50 QButtonGroup can be used to group check buttons logically, allowing
51 exclusive checkboxes. However, QButtonGroup does not provide any visual
52 representation.
53
54 The image below further illustrates the differences between exclusive and
55 non-exclusive checkboxes.
56
57 \table
58 \row \li \inlineimage checkboxes-exclusive.png
59 {Check box group that allows only one option checked}
60 \li \inlineimage checkboxes-non-exclusive.png
61 {Check box group that allows multiple options checked}
62 \endtable
63
64 Whenever a checkbox is checked or cleared, it emits the signal
65 checkStateChanged(). Connect to this signal if you want to trigger an action
66 each time the checkbox changes state. You can use isChecked() to query
67 whether or not a checkbox is checked.
68
69 In addition to the usual checked and unchecked states, QCheckBox optionally
70 provides a third state to indicate "no change". This is useful whenever you
71 need to give the user the option of neither checking nor unchecking a
72 checkbox. If you need this third state, enable it with setTristate(), and
73 use checkState() to query the current toggle state.
74
75 Just like QPushButton, a checkbox displays text, and optionally a small
76 icon. The icon is set with setIcon(). The text can be set in the
77 constructor or with setText(). A shortcut key can be specified by preceding
78 the preferred character with an ampersand. For example:
79
80 \snippet code/src_gui_widgets_qcheckbox.cpp 0
81
82 In this example, the shortcut is \e{Alt+A}. See the \l{QShortcut#mnemonic}
83 {QShortcut} documentation for details. To display an actual ampersand,
84 use '&&'.
85
86 \sa QAbstractButton, QRadioButton
87*/
88
89/*!
90 \fn void QCheckBox::stateChanged(int state)
91
92 \deprecated [6.9] Use checkStateChanged(Qt::CheckState) instead.
93
94 This signal is emitted whenever the checkbox's state changes, i.e.,
95 whenever the user checks or unchecks it.
96
97 \a state contains the checkbox's new Qt::CheckState.
98*/
99
100/*!
101 \fn void QCheckBox::checkStateChanged(Qt::CheckState state)
102 \since 6.7
103
104 This signal is emitted whenever the checkbox's state changes, i.e.,
105 whenever the user checks or unchecks it.
106
107 \a state contains the checkbox's new Qt::CheckState.
108*/
109
110/*!
111 \property QCheckBox::tristate
112 \brief whether the checkbox is a tri-state checkbox
113
114 The default is false, i.e., the checkbox has only two states.
115*/
116
118{
119 Q_Q(QCheckBox);
120 q->setCheckable(true);
121 q->setMouseTracking(true);
122 q->setForegroundRole(QPalette::WindowText);
123 q->setAttribute(Qt::WA_MacShowFocusRect);
124 setLayoutItemMargins(QStyle::SE_CheckBoxLayoutItem);
125}
126
127/*!
128 Initializes \a option with the values from this QCheckBox. This method is
129 useful for subclasses that require a QStyleOptionButton, but do not want
130 to fill in all the information themselves.
131
132 \sa QStyleOption::initFrom()
133*/
134void QCheckBox::initStyleOption(QStyleOptionButton *option) const
135{
136 if (!option)
137 return;
138 Q_D(const QCheckBox);
139 option->initFrom(this);
140 if (d->down)
141 option->state |= QStyle::State_Sunken;
142 if (d->tristate && d->noChange)
143 option->state |= QStyle::State_NoChange;
144 else
145 option->state |= d->checked ? QStyle::State_On : QStyle::State_Off;
146 if (testAttribute(Qt::WA_Hover) && underMouse()) {
147 option->state.setFlag(QStyle::State_MouseOver, d->hovering);
148 }
149 option->text = d->text;
150 option->icon = d->icon;
151 option->iconSize = iconSize();
152}
153
154/*!
155 Constructs a checkbox with the given \a parent, but with no text.
156
157 \a parent is passed on to the QAbstractButton constructor.
158*/
159
160QCheckBox::QCheckBox(QWidget *parent)
161 : QAbstractButton (*new QCheckBoxPrivate, parent)
162{
163 Q_D(QCheckBox);
164 d->init();
165}
166
167/*!
168 Constructs a checkbox with the given \a parent and \a text.
169
170 \a parent is passed on to the QAbstractButton constructor.
171*/
172
173QCheckBox::QCheckBox(const QString &text, QWidget *parent)
174 : QCheckBox(parent)
175{
176 setText(text);
177}
178
179/*!
180 Destructor.
181*/
182QCheckBox::~QCheckBox()
183{
184}
185
186void QCheckBox::setTristate(bool y)
187{
188 Q_D(QCheckBox);
189 d->tristate = y;
190}
191
192bool QCheckBox::isTristate() const
193{
194 Q_D(const QCheckBox);
195 return d->tristate;
196}
197
198
199/*!
200 Returns the checkbox's check state. If you do not need tristate support,
201 you can also use \l QAbstractButton::isChecked(), which returns a boolean.
202
203 \sa setCheckState(), Qt::CheckState
204*/
205Qt::CheckState QCheckBox::checkState() const
206{
207 Q_D(const QCheckBox);
208 if (d->tristate && d->noChange)
209 return Qt::PartiallyChecked;
210 return d->checked ? Qt::Checked : Qt::Unchecked;
211}
212
213/*!
214 Sets the checkbox's check state to \a state. If you do not need tristate
215 support, you can also use \l QAbstractButton::setChecked(), which takes a
216 boolean.
217
218 \sa checkState(), Qt::CheckState
219*/
220void QCheckBox::setCheckState(Qt::CheckState state)
221{
222 Q_D(QCheckBox);
223#if QT_CONFIG(accessibility)
224 bool noChange = d->noChange;
225#endif
226 if (state == Qt::PartiallyChecked) {
227 d->tristate = true;
228 d->noChange = true;
229 } else {
230 d->noChange = false;
231 }
232 d->blockRefresh = true;
233 setChecked(state != Qt::Unchecked);
234 d->blockRefresh = false;
235 d->refresh();
236 if (state != d->publishedState) {
237 d->publishedState = state;
238 emit checkStateChanged(state);
239#if QT_DEPRECATED_SINCE(6, 9)
240 QT_IGNORE_DEPRECATIONS(
241 emit stateChanged(state);
242 )
243#endif
244 }
245
246#if QT_CONFIG(accessibility)
247 if (noChange != d->noChange) {
248 QAccessible::State s;
249 s.checkStateMixed = true;
250 QAccessibleStateChangeEvent event(this, s);
251 QAccessible::updateAccessibility(&event);
252 }
253#endif
254}
255
256
257/*!
258 \reimp
259*/
260QSize QCheckBox::sizeHint() const
261{
262 Q_D(const QCheckBox);
263 if (d->sizeHint.isValid())
264 return d->sizeHint;
265 ensurePolished();
266 QFontMetrics fm = fontMetrics();
267 QStyleOptionButton opt;
268 initStyleOption(&opt);
269 QSize sz = style()->itemTextRect(fm, QRect(), Qt::TextShowMnemonic, false,
270 text()).size();
271 if (!opt.icon.isNull())
272 sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(sz.height(), opt.iconSize.height()));
273 d->sizeHint = style()->sizeFromContents(QStyle::CT_CheckBox, &opt, sz, this);
274 return d->sizeHint;
275}
276
277
278/*!
279 \reimp
280*/
281QSize QCheckBox::minimumSizeHint() const
282{
283 return sizeHint();
284}
285
286/*!
287 \reimp
288*/
289void QCheckBox::paintEvent(QPaintEvent *)
290{
291 QStylePainter p(this);
292 QStyleOptionButton opt;
293 initStyleOption(&opt);
294 p.drawControl(QStyle::CE_CheckBox, opt);
295}
296
297/*!
298 \reimp
299*/
300void QCheckBox::mouseMoveEvent(QMouseEvent *e)
301{
302 Q_D(QCheckBox);
303 if (testAttribute(Qt::WA_Hover)) {
304 bool hit = false;
305 if (underMouse())
306 hit = hitButton(e->position().toPoint());
307
308 if (hit != d->hovering) {
309 update(rect());
310 d->hovering = hit;
311 }
312 }
313
314 QAbstractButton::mouseMoveEvent(e);
315}
316
317
318/*!
319 \reimp
320*/
321bool QCheckBox::hitButton(const QPoint &pos) const
322{
323 QStyleOptionButton opt;
324 initStyleOption(&opt);
325 return style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, this).contains(pos);
326}
327
328/*!
329 \reimp
330*/
331void QCheckBox::checkStateSet()
332{
333 Q_D(QCheckBox);
334 d->noChange = false;
335 Qt::CheckState state = checkState();
336 if (state != d->publishedState) {
337 d->publishedState = state;
338 emit checkStateChanged(state);
339#if QT_DEPRECATED_SINCE(6, 9)
340 QT_IGNORE_DEPRECATIONS(
341 emit stateChanged(state);
342 )
343#endif
344 }
345}
346
347/*!
348 \reimp
349*/
350void QCheckBox::nextCheckState()
351{
352 Q_D(QCheckBox);
353 if (d->tristate)
354 setCheckState((Qt::CheckState)((checkState() + 1) % 3));
355 else {
356 QAbstractButton::nextCheckState();
357 QCheckBox::checkStateSet();
358 }
359}
360
361/*!
362 \reimp
363*/
364bool QCheckBox::event(QEvent *e)
365{
366 Q_D(QCheckBox);
367 if (e->type() == QEvent::StyleChange
368#ifdef Q_OS_MAC
369 || e->type() == QEvent::MacSizeChange
370#endif
371 )
372 d->setLayoutItemMargins(QStyle::SE_CheckBoxLayoutItem);
373 return QAbstractButton::event(e);
374}
375
376
377
378QT_END_NAMESPACE
379
380#include "moc_qcheckbox.cpp"
Qt::CheckState publishedState
Definition qcheckbox.cpp:32