228void QLabel::setText(
const QString &text)
234 QWidgetTextControl *oldControl = d->control;
235 d->control =
nullptr;
239 d->isTextLabel =
true;
241 if (d->textformat == Qt::AutoText) {
242 if (Qt::mightBeRichText(d->text))
243 d->effectiveTextFormat = Qt::RichText;
245 d->effectiveTextFormat = Qt::PlainText;
247 d->effectiveTextFormat = d->textformat;
250 d->control = oldControl;
252 if (d->needTextControl()) {
253 d->ensureTextControl();
256 d->control =
nullptr;
259 if (d->effectiveTextFormat != Qt::PlainText) {
260 setMouseTracking(
true);
265#ifndef QT_NO_SHORTCUT
272#if QT_CONFIG(accessibility)
273 if (accessibleName().isEmpty()) {
274 QAccessibleEvent event(
this, QAccessible::NameChanged);
275 QAccessible::updateAccessibility(&event);
514QSize QLabelPrivate::sizeForWidth(
int w)
const
517 if (q->minimumWidth() > 0)
518 w = qMax(w, q->minimumWidth());
519 QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
523 int hextra = 2 * margin;
525 QFontMetrics fm = q->fontMetrics();
527 if (icon && !icon->isNull()) {
528 br = QRect(QPoint(0, 0), pixmapSize);
530 }
else if (picture && !picture->isNull()) {
531 br = picture->boundingRect();
534 }
else if (movie && !movie->currentPixmap().isNull()) {
535 br = movie->currentPixmap().rect();
536 br.setSize(movie->currentPixmap().deviceIndependentSize().toSize());
538 }
else if (isTextLabel) {
539 int align = QStyle::visualAlignment(textDirection(), QFlag(
this->align));
543 if (m < 0 && q->frameWidth())
544 m = fm.horizontalAdvance(u'x') - margin*2;
546 if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
548 if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
553 ensureTextLayouted();
554 const qreal oldTextWidth = control->textWidth();
556 if (align & Qt::TextWordWrap) {
558 w = qMax(w-hextra-contentsMargin.width(), 0);
559 control->setTextWidth(w);
561 control->adjustSize();
564 control->setTextWidth(-1);
567 QSizeF controlSize = control->size();
568 br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
571 control->setTextWidth(oldTextWidth);
575 int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
577 flags |= Qt::TextShowMnemonic;
580 if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
581 flags |= Qt::TextHideMnemonic;
584 bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
586 w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
589 w -= (hextra + contentsMargin.width());
590 br = fm.boundingRect(0, 0, w ,2000, flags, text);
591 if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
592 br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
593 if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
594 br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
597 br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
600 const QSize contentsSize(br.width() + hextra, br.height() + vextra);
601 return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
915bool QLabel::event(QEvent *e)
918 QEvent::Type type = e->type();
920#ifndef QT_NO_SHORTCUT
921 if (type == QEvent::Shortcut) {
922 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
923 if (se->shortcutId() == d->shortcutId) {
924 QWidget *w = d->buddy;
926 return QFrame::event(e);
927 if (w->focusPolicy() != Qt::NoFocus)
928 w->setFocus(Qt::ShortcutFocusReason);
929#if QT_CONFIG(abstractbutton)
930 QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
931 if (button && !se->isAmbiguous())
932 button->animateClick();
935 window()->setAttribute(Qt::WA_KeyboardFocusChange);
940 if (type == QEvent::Resize) {
942 d->textLayoutDirty =
true;
943 }
else if (e->type() == QEvent::StyleChange
945 || e->type() == QEvent::MacSizeChange
948 d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
950 }
else if (type == QEvent::Polish) {
951 if (d->needTextControl())
952 d->ensureTextControl();
955 return QFrame::event(e);
960void QLabel::paintEvent(QPaintEvent *)
963 QStyle *style = QWidget::style();
964 QPainter painter(
this);
966 QRect cr = contentsRect();
967 cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
968 int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
969 : layoutDirection(), QFlag(d->align));
972 if (d->movie && !d->movie->currentPixmap().isNull()) {
973 if (d->scaledcontents)
974 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
976 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
980 if (d->isTextLabel) {
981 QRectF lr = d->layoutRect().toAlignedRect();
984#ifndef QT_NO_STYLE_STYLESHEET
985 if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
986 cssStyle->styleSheetPalette(
this, &opt, &opt.palette);
989#ifndef QT_NO_SHORTCUT
990 const bool underline =
static_cast<
bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
991 nullptr,
this,
nullptr));
992 if (d->shortcutId != 0
993 && underline != d->shortcutCursor.charFormat().fontUnderline()) {
995 fmt.setFontUnderline(underline);
996 d->shortcutCursor.mergeCharFormat(fmt);
999 d->ensureTextLayouted();
1001 QAbstractTextDocumentLayout::PaintContext context;
1003 context.palette = opt.palette;
1005 if (foregroundRole() != QPalette::Text && isEnabled())
1006 context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
1009 painter.translate(lr.topLeft());
1010 painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
1011 d->control->setPalette(context.palette);
1012 d->control->drawContents(&painter, QRectF(),
this);
1015 int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
1016 : Qt::TextForceRightToLeft);
1017 if (d->hasShortcut) {
1018 flags |= Qt::TextShowMnemonic;
1019 if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt,
this))
1020 flags |= Qt::TextHideMnemonic;
1022 style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
1025#ifndef QT_NO_PICTURE
1027 QRect br = d->picture->boundingRect();
1028 int rw = br.width();
1029 int rh = br.height();
1030 if (d->scaledcontents) {
1032 painter.translate(cr.x(), cr.y());
1033 painter.scale((
double)cr.width()/rw, (
double)cr.height()/rh);
1034 painter.drawPicture(-br.x(), -br.y(), *d->picture);
1039 if (align & Qt::AlignVCenter)
1040 yo = (cr.height()-rh)/2;
1041 else if (align & Qt::AlignBottom)
1042 yo = cr.height()-rh;
1043 if (align & Qt::AlignRight)
1045 else if (align & Qt::AlignHCenter)
1046 xo = (cr.width()-rw)/2;
1047 painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
1051 if (d->icon && !d->icon->isNull()) {
1052 const qreal dpr = devicePixelRatio();
1053 const QSize size = d->scaledcontents ? cr.size() : d->pixmapSize;
1054 const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
1055 QPixmap pix = d->icon->pixmap(size, dpr, mode);
1056 if (d->scaledcontents && pix.size() != size * dpr) {
1057 pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1058 pix.setDevicePixelRatio(dpr);
1059 d->icon->addPixmap(pix, mode);
1063 style->drawItemPixmap(&painter, cr, align, pix);
1419QRect QLabelPrivate::documentRect()
const
1422 Q_ASSERT_X(isTextLabel,
"documentRect",
"document rect called for label that is not a text label!");
1423 QRect cr = q->contentsRect();
1424 cr.adjust(margin, margin, -margin, -margin);
1425 const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
1426 : q->layoutDirection(), QFlag(
this->align));
1428 if (m < 0 && q->frameWidth())
1429 m = q->fontMetrics().horizontalAdvance(u'x') / 2 - margin;
1431 if (align & Qt::AlignLeft)
1432 cr.setLeft(cr.left() + m);
1433 if (align & Qt::AlignRight)
1434 cr.setRight(cr.right() - m);
1435 if (align & Qt::AlignTop)
1436 cr.setTop(cr.top() + m);
1437 if (align & Qt::AlignBottom)
1438 cr.setBottom(cr.bottom() - m);
1443void QLabelPrivate::ensureTextPopulated()
const
1448 QTextDocument *doc = control->document();
1450 if (effectiveTextFormat == Qt::PlainText) {
1451 doc->setPlainText(text);
1452#if QT_CONFIG(texthtmlparser)
1453 }
else if (effectiveTextFormat == Qt::RichText) {
1456#if QT_CONFIG(textmarkdownreader)
1457 }
else if (effectiveTextFormat == Qt::MarkdownText) {
1458 doc->setMarkdown(text);
1461 doc->setPlainText(text);
1463 doc->setUndoRedoEnabled(
false);
1465#ifndef QT_NO_SHORTCUT
1471 while (!(cursor = control->document()->find((
"&"_L1), from)).isNull()) {
1472 cursor.deleteChar();
1473 cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
1474 from = cursor.position();
1475 if (!found && cursor.selectedText() !=
"&"_L1) {
1477 shortcutCursor = cursor;
1487void QLabelPrivate::ensureTextLayouted()
const
1489 if (!textLayoutDirty)
1491 ensureTextPopulated();
1493 QTextDocument *doc = control->document();
1494 QTextOption opt = doc->defaultTextOption();
1496 opt.setAlignment(QFlag(
this->align));
1498 if (
this->align & Qt::TextWordWrap)
1499 opt.setWrapMode(QTextOption::WordWrap);
1501 opt.setWrapMode(QTextOption::ManualWrap);
1503 doc->setDefaultTextOption(opt);
1505 QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
1507 doc->rootFrame()->setFrameFormat(fmt);
1508 doc->setTextWidth(documentRect().width());
1510 textLayoutDirty =
false;
1513void QLabelPrivate::ensureTextControl()
const
1519 control =
new QWidgetTextControl(
const_cast<QLabel *>(q));
1520 control->document()->setUndoRedoEnabled(
false);
1521 control->document()->setDefaultFont(q->font());
1522 if (resourceProvider !=
nullptr)
1523 control->document()->setResourceProvider(resourceProvider);
1524 control->setTextInteractionFlags(textInteractionFlags);
1525 control->setOpenExternalLinks(openExternalLinks);
1526 control->setPalette(q->palette());
1527 control->setFocus(q->hasFocus());
1528 QObject::connect(control, &QWidgetTextControl::updateRequest,
1529 q, qOverload<>(&QLabel::update));
1530 QObject::connect(control, &QWidgetTextControl::linkActivated,
1531 q, &QLabel::linkActivated);
1532 QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
1533 this, &QLabelPrivate::linkHovered);
1534 textLayoutDirty =
true;
1574QRectF QLabelPrivate::layoutRect()
const
1576 QRectF cr = documentRect();
1579 ensureTextLayouted();
1581 qreal rh = control->document()->documentLayout()->documentSize().height();
1583 if (align & Qt::AlignVCenter)
1584 yo = qMax((cr.height()-rh)/2, qreal(0));
1585 else if (align & Qt::AlignBottom)
1586 yo = qMax(cr.height()-rh, qreal(0));
1587 return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height());