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
qquicklabel.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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
10
11#include <QtQuick/private/qquickitem_p.h>
12#include <QtQuick/private/qquicktext_p.h>
13
14#if QT_CONFIG(accessibility)
15#include <QtQuick/private/qquickaccessibleattached_p.h>
16#endif
17
19
20/*!
21 \qmltype Label
22 \inherits Text
23//! \nativetype QQuickLabel
24 \inqmlmodule QtQuick.Controls
25 \since 5.7
26 \ingroup text
27 \brief Styled text label with inherited font.
28
29 Label extends \l Text with styling and \l {Control::font}{font}
30 inheritance. The default colors and font are style specific. Label
31 can also have a visual \l background item.
32
33 \image qtquickcontrols-label.png
34 {Label displaying text with styling}
35
36 \snippet qtquickcontrols-label.qml 1
37
38 You can use the properties of \l Text to change the appearance of the text as desired:
39
40 \qml
41 Label {
42 text: "Hello world"
43 font.pixelSize: 22
44 font.italic: true
45 }
46 \endqml
47
48 \sa {Customizing Label}
49*/
50
51QQuickLabelPrivate::QQuickLabelPrivate()
52{
53#if QT_CONFIG(accessibility)
54 QAccessible::installActivationObserver(this);
55 setAccessible();
56#endif
57}
58
59QQuickLabelPrivate::~QQuickLabelPrivate()
60{
61#if QT_CONFIG(accessibility)
62 QAccessible::removeActivationObserver(this);
63#endif
64}
65
66void QQuickLabelPrivate::setTopInset(qreal value, bool reset)
67{
68 Q_Q(QQuickLabel);
69 const QMarginsF oldInset = getInset();
70 extra.value().topInset = value;
71 extra.value().hasTopInset = !reset;
72 if (!qFuzzyCompare(oldInset.top(), value)) {
73 emit q->topInsetChanged();
74 q->insetChange(getInset(), oldInset);
75 }
76}
77
78void QQuickLabelPrivate::setLeftInset(qreal value, bool reset)
79{
80 Q_Q(QQuickLabel);
81 const QMarginsF oldInset = getInset();
82 extra.value().leftInset = value;
83 extra.value().hasLeftInset = !reset;
84 if (!qFuzzyCompare(oldInset.left(), value)) {
85 emit q->leftInsetChanged();
86 q->insetChange(getInset(), oldInset);
87 }
88}
89
90void QQuickLabelPrivate::setRightInset(qreal value, bool reset)
91{
92 Q_Q(QQuickLabel);
93 const QMarginsF oldInset = getInset();
94 extra.value().rightInset = value;
95 extra.value().hasRightInset = !reset;
96 if (!qFuzzyCompare(oldInset.right(), value)) {
97 emit q->rightInsetChanged();
98 q->insetChange(getInset(), oldInset);
99 }
100}
101
102void QQuickLabelPrivate::setBottomInset(qreal value, bool reset)
103{
104 Q_Q(QQuickLabel);
105 const QMarginsF oldInset = getInset();
106 extra.value().bottomInset = value;
107 extra.value().hasBottomInset = !reset;
108 if (!qFuzzyCompare(oldInset.bottom(), value)) {
109 emit q->bottomInsetChanged();
110 q->insetChange(getInset(), oldInset);
111 }
112}
113
114void QQuickLabelPrivate::resizeBackground()
115{
116 if (!background)
117 return;
118
119 resizingBackground = true;
120
121 QQuickItemPrivate *p = QQuickItemPrivate::get(background);
122 if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x()))
123 || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
124 background->setX(getLeftInset());
125 background->setWidth(width - getLeftInset() - getRightInset());
126 }
127 if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y()))
128 || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
129 background->setY(getTopInset());
130 background->setHeight(height - getTopInset() - getBottomInset());
131 }
132
133 resizingBackground = false;
134}
135
136/*!
137 \internal
138
139 Determine which font is implicitly imposed on this control by its ancestors
140 and QGuiApplication::font, resolve this against its own font (attributes from
141 the implicit font are copied over). Then propagate this font to this
142 control's children.
143*/
144void QQuickLabelPrivate::resolveFont()
145{
146 Q_Q(QQuickLabel);
147 inheritFont(QQuickControlPrivate::parentFont(q));
148}
149
150void QQuickLabelPrivate::inheritFont(const QFont &font)
151{
152 QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
153 parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask());
154
155 const QFont defaultFont = QQuickTheme::font(QQuickTheme::Label);
156 QFont resolvedFont = parentFont.resolve(defaultFont);
157
158 setFont_helper(resolvedFont);
159}
160
161/*!
162 \internal
163
164 Assign \a font to this control, and propagate it to all children.
165*/
166void QQuickLabelPrivate::updateFont(const QFont &font)
167{
168 Q_Q(QQuickLabel);
169 QFont oldFont = sourceFont;
170 q->QQuickText::setFont(font);
171
172 QQuickControlPrivate::updateFontRecur(q, font);
173
174 if (oldFont != font)
175 emit q->fontChanged();
176}
177
178void QQuickLabelPrivate::textChanged(const QString &text)
179{
180#if QT_CONFIG(accessibility)
181 maybeSetAccessibleName(text);
182#else
183 Q_UNUSED(text);
184#endif
185}
186
187#if QT_CONFIG(accessibility)
188void QQuickLabelPrivate::accessibilityActiveChanged(bool active)
189{
190 if (!active)
191 return;
192
193 Q_Q(QQuickLabel);
194 QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
195 Q_ASSERT(accessibleAttached);
196 accessibleAttached->setRole(effectiveAccessibleRole());
197 maybeSetAccessibleName(text);
198}
199
200QAccessible::Role QQuickLabelPrivate::accessibleRole() const
201{
202 return QAccessible::StaticText;
203}
204
205void QQuickLabelPrivate::maybeSetAccessibleName(const QString &name)
206{
207 Q_Q(QQuickLabel);
208 auto accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(
209 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
210 if (accessibleAttached) {
211 if (!accessibleAttached->wasNameExplicitlySet())
212 accessibleAttached->setNameImplicitly(name);
213 }
214}
215#endif
216
217void QQuickLabelPrivate::cancelBackground()
218{
219 Q_Q(QQuickLabel);
220 quickCancelDeferred(q, backgroundName());
221}
222
223void QQuickLabelPrivate::executeBackground(bool complete)
224{
225 Q_Q(QQuickLabel);
226 if (background.wasExecuted())
227 return;
228
229 if (!background || complete)
230 quickBeginDeferred(q, backgroundName(), background);
231 if (complete)
232 quickCompleteDeferred(q, backgroundName(), background);
233}
234
235void QQuickLabelPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
236{
237 Q_UNUSED(diff);
238 if (resizingBackground || item != background || !change.sizeChange())
239 return;
240
241 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
242 extra.value().hasBackgroundWidth = p->widthValid();
243 extra.value().hasBackgroundHeight = p->heightValid();
244 resizeBackground();
245}
246
247void QQuickLabelPrivate::itemImplicitWidthChanged(QQuickItem *item)
248{
249 Q_Q(QQuickLabel);
250 if (item == background)
251 emit q->implicitBackgroundWidthChanged();
252}
253
254void QQuickLabelPrivate::itemImplicitHeightChanged(QQuickItem *item)
255{
256 Q_Q(QQuickLabel);
257 if (item == background)
258 emit q->implicitBackgroundHeightChanged();
259}
260
261void QQuickLabelPrivate::itemDestroyed(QQuickItem *item)
262{
263 Q_Q(QQuickLabel);
264 if (item == background) {
265 background = nullptr;
266 emit q->implicitBackgroundWidthChanged();
267 emit q->implicitBackgroundHeightChanged();
268 }
269}
270
271QPalette QQuickLabelPrivate::defaultPalette() const
272{
273 return QQuickTheme::palette(QQuickTheme::Label);
274}
275
276QQuickLabel::QQuickLabel(QQuickItem *parent)
277 : QQuickText(*(new QQuickLabelPrivate), parent)
278{
279 Q_D(QQuickLabel);
280 QObjectPrivate::connect(this, &QQuickText::textChanged, d, &QQuickLabelPrivate::textChanged);
281}
282
283QQuickLabel::~QQuickLabel()
284{
285 Q_D(QQuickLabel);
286 QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
287}
288
289QFont QQuickLabel::font() const
290{
291 Q_D(const QQuickLabel);
292 QFont font = QQuickText::font();
293 // The resolve mask should inherit from the requestedFont
294 font.setResolveMask(d->extra.isAllocated() ? d->extra->requestedFont.resolveMask() : 0);
295 return font;
296}
297
298void QQuickLabel::setFont(const QFont &font)
299{
300 Q_D(QQuickLabel);
301 if (d->extra.isAllocated()
302 && d->extra.value().requestedFont.resolveMask() == font.resolveMask()
303 && d->extra.value().requestedFont == font)
304 return;
305
306 d->extra.value().requestedFont = font;
307 d->resolveFont();
308}
309
310/*!
311 \qmlproperty Item QtQuick.Controls::Label::background
312
313 This property holds the background item.
314
315 \note If the background item has no explicit size specified, it automatically
316 follows the control's size. In most cases, there is no need to specify
317 width or height for a background item.
318
319 \sa {Customizing Label}
320*/
321QQuickItem *QQuickLabel::background() const
322{
323 QQuickLabelPrivate *d = const_cast<QQuickLabelPrivate *>(d_func());
324 if (!d->background)
325 d->executeBackground();
326 return d->background;
327}
328
329void QQuickLabel::setBackground(QQuickItem *background)
330{
331 Q_D(QQuickLabel);
332 if (d->background == background)
333 return;
334
335 if (!d->background.isExecuting())
336 d->cancelBackground();
337
338 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
339 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
340
341 if (d->extra.isAllocated()) {
342 d->extra.value().hasBackgroundWidth = false;
343 d->extra.value().hasBackgroundHeight = false;
344 }
345
346 QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
347 QQuickControlPrivate::hideOldItem(d->background);
348 d->background = background;
349
350 if (background) {
351 background->setParentItem(this);
352 if (qFuzzyIsNull(background->z()))
353 background->setZ(-1);
354 QQuickItemPrivate *p = QQuickItemPrivate::get(background);
355 if (p->widthValid() || p->heightValid()) {
356 d->extra.value().hasBackgroundWidth = p->widthValid();
357 d->extra.value().hasBackgroundHeight = p->heightValid();
358 }
359 if (isComponentComplete())
360 d->resizeBackground();
361 QQuickControlPrivate::addImplicitSizeListener(background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
362 }
363
364 if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth()))
365 emit implicitBackgroundWidthChanged();
366 if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight()))
367 emit implicitBackgroundHeightChanged();
368 if (!d->background.isExecuting())
369 emit backgroundChanged();
370}
371
372/*!
373 \since QtQuick.Controls 2.5 (Qt 5.12)
374 \qmlproperty real QtQuick.Controls::Label::implicitBackgroundWidth
375 \readonly
376
377 This property holds the implicit background width.
378
379 The value is equal to \c {background ? background.implicitWidth : 0}.
380
381 \sa implicitBackgroundHeight
382*/
383qreal QQuickLabel::implicitBackgroundWidth() const
384{
385 Q_D(const QQuickLabel);
386 if (!d->background)
387 return 0;
388 return d->background->implicitWidth();
389}
390
391/*!
392 \since QtQuick.Controls 2.5 (Qt 5.12)
393 \qmlproperty real QtQuick.Controls::Label::implicitBackgroundHeight
394 \readonly
395
396 This property holds the implicit background height.
397
398 The value is equal to \c {background ? background.implicitHeight : 0}.
399
400 \sa implicitBackgroundWidth
401*/
402qreal QQuickLabel::implicitBackgroundHeight() const
403{
404 Q_D(const QQuickLabel);
405 if (!d->background)
406 return 0;
407 return d->background->implicitHeight();
408}
409
410/*!
411 \since QtQuick.Controls 2.5 (Qt 5.12)
412 \qmlproperty real QtQuick.Controls::Label::topInset
413
414 This property holds the top inset for the background.
415
416 \sa {Control Layout}, bottomInset
417*/
418qreal QQuickLabel::topInset() const
419{
420 Q_D(const QQuickLabel);
421 return d->getTopInset();
422}
423
424void QQuickLabel::setTopInset(qreal inset)
425{
426 Q_D(QQuickLabel);
427 d->setTopInset(inset);
428}
429
430void QQuickLabel::resetTopInset()
431{
432 Q_D(QQuickLabel);
433 d->setTopInset(0, true);
434}
435
436/*!
437 \since QtQuick.Controls 2.5 (Qt 5.12)
438 \qmlproperty real QtQuick.Controls::Label::leftInset
439
440 This property holds the left inset for the background.
441
442 \sa {Control Layout}, rightInset
443*/
444qreal QQuickLabel::leftInset() const
445{
446 Q_D(const QQuickLabel);
447 return d->getLeftInset();
448}
449
450void QQuickLabel::setLeftInset(qreal inset)
451{
452 Q_D(QQuickLabel);
453 d->setLeftInset(inset);
454}
455
456void QQuickLabel::resetLeftInset()
457{
458 Q_D(QQuickLabel);
459 d->setLeftInset(0, true);
460}
461
462/*!
463 \since QtQuick.Controls 2.5 (Qt 5.12)
464 \qmlproperty real QtQuick.Controls::Label::rightInset
465
466 This property holds the right inset for the background.
467
468 \sa {Control Layout}, leftInset
469*/
470qreal QQuickLabel::rightInset() const
471{
472 Q_D(const QQuickLabel);
473 return d->getRightInset();
474}
475
476void QQuickLabel::setRightInset(qreal inset)
477{
478 Q_D(QQuickLabel);
479 d->setRightInset(inset);
480}
481
482void QQuickLabel::resetRightInset()
483{
484 Q_D(QQuickLabel);
485 d->setRightInset(0, true);
486}
487
488/*!
489 \since QtQuick.Controls 2.5 (Qt 5.12)
490 \qmlproperty real QtQuick.Controls::Label::bottomInset
491
492 This property holds the bottom inset for the background.
493
494 \sa {Control Layout}, topInset
495*/
496qreal QQuickLabel::bottomInset() const
497{
498 Q_D(const QQuickLabel);
499 return d->getBottomInset();
500}
501
502void QQuickLabel::setBottomInset(qreal inset)
503{
504 Q_D(QQuickLabel);
505 d->setBottomInset(inset);
506}
507
508void QQuickLabel::resetBottomInset()
509{
510 Q_D(QQuickLabel);
511 d->setBottomInset(0, true);
512}
513
514void QQuickLabel::classBegin()
515{
516 Q_D(QQuickLabel);
517 QQuickText::classBegin();
518 d->resolveFont();
519}
520
521void QQuickLabel::componentComplete()
522{
523 Q_D(QQuickLabel);
524 d->executeBackground(true);
525 QQuickText::componentComplete();
526 d->resizeBackground();
527#if QT_CONFIG(accessibility)
528 if (QAccessible::isActive())
529 d->accessibilityActiveChanged(true);
530#endif
531}
532
533void QQuickLabel::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
534{
535 Q_D(QQuickLabel);
536 QQuickText::itemChange(change, value);
537 switch (change) {
538 case ItemEnabledHasChanged:
539 break;
540 case ItemSceneChange:
541 case ItemParentHasChanged:
542 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
543 d->resolveFont();
544 }
545 break;
546 default:
547 break;
548 }
549}
550
551void QQuickLabel::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
552{
553 Q_D(QQuickLabel);
554 QQuickText::geometryChange(newGeometry, oldGeometry);
555 d->resizeBackground();
556}
557
558void QQuickLabel::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
559{
560 Q_D(QQuickLabel);
561 Q_UNUSED(newInset);
562 Q_UNUSED(oldInset);
563 d->resizeBackground();
564}
565
566QT_END_NAMESPACE
567
568#include "moc_qquicklabel_p.cpp"
Combined button and popup list for selecting options.