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