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.value().requestedFont.resolveMask());
295 return font;
296}
297
298void QQuickLabel::setFont(const QFont &font)
299{
300 Q_D(QQuickLabel);
301 if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font)
302 return;
303
304 d->extra.value().requestedFont = font;
305 d->resolveFont();
306}
307
308/*!
309 \qmlproperty Item QtQuick.Controls::Label::background
310
311 This property holds the background item.
312
313 \note If the background item has no explicit size specified, it automatically
314 follows the control's size. In most cases, there is no need to specify
315 width or height for a background item.
316
317 \sa {Customizing Label}
318*/
319QQuickItem *QQuickLabel::background() const
320{
321 QQuickLabelPrivate *d = const_cast<QQuickLabelPrivate *>(d_func());
322 if (!d->background)
323 d->executeBackground();
324 return d->background;
325}
326
327void QQuickLabel::setBackground(QQuickItem *background)
328{
329 Q_D(QQuickLabel);
330 if (d->background == background)
331 return;
332
333 if (!d->background.isExecuting())
334 d->cancelBackground();
335
336 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
337 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
338
339 if (d->extra.isAllocated()) {
340 d->extra.value().hasBackgroundWidth = false;
341 d->extra.value().hasBackgroundHeight = false;
342 }
343
344 QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
345 QQuickControlPrivate::hideOldItem(d->background);
346 d->background = background;
347
348 if (background) {
349 background->setParentItem(this);
350 if (qFuzzyIsNull(background->z()))
351 background->setZ(-1);
352 QQuickItemPrivate *p = QQuickItemPrivate::get(background);
353 if (p->widthValid() || p->heightValid()) {
354 d->extra.value().hasBackgroundWidth = p->widthValid();
355 d->extra.value().hasBackgroundHeight = p->heightValid();
356 }
357 if (isComponentComplete())
358 d->resizeBackground();
359 QQuickControlPrivate::addImplicitSizeListener(background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
360 }
361
362 if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth()))
363 emit implicitBackgroundWidthChanged();
364 if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight()))
365 emit implicitBackgroundHeightChanged();
366 if (!d->background.isExecuting())
367 emit backgroundChanged();
368}
369
370/*!
371 \since QtQuick.Controls 2.5 (Qt 5.12)
372 \qmlproperty real QtQuick.Controls::Label::implicitBackgroundWidth
373 \readonly
374
375 This property holds the implicit background width.
376
377 The value is equal to \c {background ? background.implicitWidth : 0}.
378
379 \sa implicitBackgroundHeight
380*/
381qreal QQuickLabel::implicitBackgroundWidth() const
382{
383 Q_D(const QQuickLabel);
384 if (!d->background)
385 return 0;
386 return d->background->implicitWidth();
387}
388
389/*!
390 \since QtQuick.Controls 2.5 (Qt 5.12)
391 \qmlproperty real QtQuick.Controls::Label::implicitBackgroundHeight
392 \readonly
393
394 This property holds the implicit background height.
395
396 The value is equal to \c {background ? background.implicitHeight : 0}.
397
398 \sa implicitBackgroundWidth
399*/
400qreal QQuickLabel::implicitBackgroundHeight() const
401{
402 Q_D(const QQuickLabel);
403 if (!d->background)
404 return 0;
405 return d->background->implicitHeight();
406}
407
408/*!
409 \since QtQuick.Controls 2.5 (Qt 5.12)
410 \qmlproperty real QtQuick.Controls::Label::topInset
411
412 This property holds the top inset for the background.
413
414 \sa {Control Layout}, bottomInset
415*/
416qreal QQuickLabel::topInset() const
417{
418 Q_D(const QQuickLabel);
419 return d->getTopInset();
420}
421
422void QQuickLabel::setTopInset(qreal inset)
423{
424 Q_D(QQuickLabel);
425 d->setTopInset(inset);
426}
427
428void QQuickLabel::resetTopInset()
429{
430 Q_D(QQuickLabel);
431 d->setTopInset(0, true);
432}
433
434/*!
435 \since QtQuick.Controls 2.5 (Qt 5.12)
436 \qmlproperty real QtQuick.Controls::Label::leftInset
437
438 This property holds the left inset for the background.
439
440 \sa {Control Layout}, rightInset
441*/
442qreal QQuickLabel::leftInset() const
443{
444 Q_D(const QQuickLabel);
445 return d->getLeftInset();
446}
447
448void QQuickLabel::setLeftInset(qreal inset)
449{
450 Q_D(QQuickLabel);
451 d->setLeftInset(inset);
452}
453
454void QQuickLabel::resetLeftInset()
455{
456 Q_D(QQuickLabel);
457 d->setLeftInset(0, true);
458}
459
460/*!
461 \since QtQuick.Controls 2.5 (Qt 5.12)
462 \qmlproperty real QtQuick.Controls::Label::rightInset
463
464 This property holds the right inset for the background.
465
466 \sa {Control Layout}, leftInset
467*/
468qreal QQuickLabel::rightInset() const
469{
470 Q_D(const QQuickLabel);
471 return d->getRightInset();
472}
473
474void QQuickLabel::setRightInset(qreal inset)
475{
476 Q_D(QQuickLabel);
477 d->setRightInset(inset);
478}
479
480void QQuickLabel::resetRightInset()
481{
482 Q_D(QQuickLabel);
483 d->setRightInset(0, true);
484}
485
486/*!
487 \since QtQuick.Controls 2.5 (Qt 5.12)
488 \qmlproperty real QtQuick.Controls::Label::bottomInset
489
490 This property holds the bottom inset for the background.
491
492 \sa {Control Layout}, topInset
493*/
494qreal QQuickLabel::bottomInset() const
495{
496 Q_D(const QQuickLabel);
497 return d->getBottomInset();
498}
499
500void QQuickLabel::setBottomInset(qreal inset)
501{
502 Q_D(QQuickLabel);
503 d->setBottomInset(inset);
504}
505
506void QQuickLabel::resetBottomInset()
507{
508 Q_D(QQuickLabel);
509 d->setBottomInset(0, true);
510}
511
512void QQuickLabel::classBegin()
513{
514 Q_D(QQuickLabel);
515 QQuickText::classBegin();
516 d->resolveFont();
517}
518
519void QQuickLabel::componentComplete()
520{
521 Q_D(QQuickLabel);
522 d->executeBackground(true);
523 QQuickText::componentComplete();
524 d->resizeBackground();
525#if QT_CONFIG(accessibility)
526 if (QAccessible::isActive())
527 d->accessibilityActiveChanged(true);
528#endif
529}
530
531void QQuickLabel::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
532{
533 Q_D(QQuickLabel);
534 QQuickText::itemChange(change, value);
535 switch (change) {
536 case ItemEnabledHasChanged:
537 break;
538 case ItemSceneChange:
539 case ItemParentHasChanged:
540 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
541 d->resolveFont();
542 }
543 break;
544 default:
545 break;
546 }
547}
548
549void QQuickLabel::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
550{
551 Q_D(QQuickLabel);
552 QQuickText::geometryChange(newGeometry, oldGeometry);
553 d->resizeBackground();
554}
555
556void QQuickLabel::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
557{
558 Q_D(QQuickLabel);
559 Q_UNUSED(newInset);
560 Q_UNUSED(oldInset);
561 d->resizeBackground();
562}
563
564QT_END_NAMESPACE
565
566#include "moc_qquicklabel_p.cpp"
Combined button and popup list for selecting options.