533QSize QLabelPrivate::sizeForWidth(
int w)
const
536 if (q->minimumWidth() > 0)
537 w = qMax(w, q->minimumWidth());
538 QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
542 int hextra = 2 * margin;
544 QFontMetrics fm = q->fontMetrics();
546 if (icon && !icon->isNull()) {
547 br = QRect(QPoint(0, 0), pixmapSize);
549 }
else if (picture && !picture->isNull()) {
550 br = picture->boundingRect();
553 }
else if (movie && !movie->currentPixmap().isNull()) {
554 br = movie->currentPixmap().rect();
555 br.setSize(movie->currentPixmap().deviceIndependentSize().toSize());
557 }
else if (isTextLabel) {
558 int align = QStyle::visualAlignment(textDirection(), QFlag(
this->align));
562 if (m < 0 && q->frameWidth())
563 m = fm.horizontalAdvance(u'x') - margin*2;
565 if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
567 if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
572 ensureTextLayouted();
573 const qreal oldTextWidth = control->textWidth();
575 if (align & Qt::TextWordWrap) {
577 w = qMax(w-hextra-contentsMargin.width(), 0);
578 control->setTextWidth(w);
580 control->adjustSize();
583 control->setTextWidth(-1);
586 QSizeF controlSize = control->size();
587 br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
590 control->setTextWidth(oldTextWidth);
594 int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
596 flags |= Qt::TextShowMnemonic;
599 if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
600 flags |= Qt::TextHideMnemonic;
603 bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
605 w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
608 w -= (hextra + contentsMargin.width());
609 br = fm.boundingRect(0, 0, w ,2000, flags, text);
610 if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
611 br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
612 if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
613 br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
616 br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
619 const QSize contentsSize(br.width() + hextra, br.height() + vextra);
620 return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
988void QLabel::paintEvent(QPaintEvent *)
991 QStyle *style = QWidget::style();
992 QPainter painter(
this);
994 QRect cr = contentsRect();
995 cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
996 int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
997 : layoutDirection(), QFlag(d->align));
1000 if (d->movie && !d->movie->currentPixmap().isNull()) {
1001 if (d->scaledcontents)
1002 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
1004 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
1008 if (d->isTextLabel) {
1009 QRectF lr = d->layoutRect().toAlignedRect();
1012#if QT_CONFIG(style_stylesheet)
1013 if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
1014 cssStyle->styleSheetPalette(
this, &opt, &opt.palette);
1017#ifndef QT_NO_SHORTCUT
1018 const bool underline =
static_cast<
bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
1019 nullptr,
this,
nullptr));
1020 if (d->shortcutId != 0
1021 && underline != d->shortcutCursor.charFormat().fontUnderline()) {
1022 QTextCharFormat fmt;
1023 fmt.setFontUnderline(underline);
1024 d->shortcutCursor.mergeCharFormat(fmt);
1027 d->ensureTextLayouted();
1029 QAbstractTextDocumentLayout::PaintContext context;
1031 context.palette = opt.palette;
1033 if (foregroundRole() != QPalette::Text && isEnabled())
1034 context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
1037 painter.translate(lr.topLeft());
1038 painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
1039 d->control->setPalette(context.palette);
1040 d->control->drawContents(&painter, QRectF(),
this);
1043 int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
1044 : Qt::TextForceRightToLeft);
1045 if (d->hasShortcut) {
1046 flags |= Qt::TextShowMnemonic;
1047 if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt,
this))
1048 flags |= Qt::TextHideMnemonic;
1050 style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
1053#ifndef QT_NO_PICTURE
1055 QRect br = d->picture->boundingRect();
1056 int rw = br.width();
1057 int rh = br.height();
1058 if (d->scaledcontents) {
1060 painter.translate(cr.x(), cr.y());
1061 painter.scale((
double)cr.width()/rw, (
double)cr.height()/rh);
1062 painter.drawPicture(-br.x(), -br.y(), *d->picture);
1067 if (align & Qt::AlignVCenter)
1068 yo = (cr.height()-rh)/2;
1069 else if (align & Qt::AlignBottom)
1070 yo = cr.height()-rh;
1071 if (align & Qt::AlignRight)
1073 else if (align & Qt::AlignHCenter)
1074 xo = (cr.width()-rw)/2;
1075 painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
1079 if (d->icon && !d->icon->isNull()) {
1080 const qreal dpr = devicePixelRatio();
1081 const QSize size = d->scaledcontents ? cr.size() : d->pixmapSize;
1082 const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
1083 QPixmap pix = d->icon->pixmap(size, dpr, mode);
1089 if (pix.size() != size * dpr) {
1090 const QString key =
"qt_label_"_L1 % HexString<quint64>(pix.cacheKey())
1091 % HexString<quint8>(mode)
1092 % HexString<uint>(size.width())
1093 % HexString<uint>(size.height())
1094 % HexString<quint16>(qRound(dpr * 1000));
1095 if (!QPixmapCache::find(key, &pix)) {
1096 pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1097 pix.setDevicePixelRatio(dpr);
1103 QPixmapCache::insert(key, pix);
1108 style->drawItemPixmap(&painter, cr, align, pix);
1468QRect QLabelPrivate::documentRect()
const
1471 Q_ASSERT_X(isTextLabel,
"documentRect",
"document rect called for label that is not a text label!");
1472 QRect cr = q->contentsRect();
1473 cr.adjust(margin, margin, -margin, -margin);
1474 const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
1475 : q->layoutDirection(), QFlag(
this->align));
1477 if (m < 0 && q->frameWidth())
1478 m = q->fontMetrics().horizontalAdvance(u'x') / 2 - margin;
1480 if (align & Qt::AlignLeft)
1481 cr.setLeft(cr.left() + m);
1482 if (align & Qt::AlignRight)
1483 cr.setRight(cr.right() - m);
1484 if (align & Qt::AlignTop)
1485 cr.setTop(cr.top() + m);
1486 if (align & Qt::AlignBottom)
1487 cr.setBottom(cr.bottom() - m);
1562void QLabelPrivate::ensureTextControl()
const
1568 control =
new QWidgetTextControl(
const_cast<QLabel *>(q));
1569 control->document()->setUndoRedoEnabled(
false);
1570 control->document()->setDefaultFont(q->font());
1571 if (resourceProvider !=
nullptr)
1572 control->document()->setResourceProvider(resourceProvider);
1573 control->setTextInteractionFlags(textInteractionFlags);
1574 control->setOpenExternalLinks(openExternalLinks);
1575 control->setPalette(q->palette());
1576 control->setFocus(q->hasFocus());
1577 QObject::connect(control, &QWidgetTextControl::updateRequest,
1578 q, qOverload<>(&QLabel::update));
1579 QObject::connect(control, &QWidgetTextControl::linkActivated,
1580 q, &QLabel::linkActivated);
1581 QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
1582 this, &QLabelPrivate::linkHovered);
1583 textLayoutDirty =
true;