524QSize QLabelPrivate::sizeForWidth(
int w)
const
527 if (q->minimumWidth() > 0)
528 w = qMax(w, q->minimumWidth());
529 QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
533 int hextra = 2 * margin;
535 QFontMetrics fm = q->fontMetrics();
537 if (icon && !icon->isNull()) {
538 br = QRect(QPoint(0, 0), pixmapSize);
540 }
else if (picture && !picture->isNull()) {
541 br = picture->boundingRect();
544 }
else if (movie && !movie->currentPixmap().isNull()) {
545 br = movie->currentPixmap().rect();
546 br.setSize(movie->currentPixmap().deviceIndependentSize().toSize());
548 }
else if (isTextLabel) {
549 int align = QStyle::visualAlignment(textDirection(), QFlag(
this->align));
553 if (m < 0 && q->frameWidth())
554 m = fm.horizontalAdvance(u'x') - margin*2;
556 if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
558 if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
563 ensureTextLayouted();
564 const qreal oldTextWidth = control->textWidth();
566 if (align & Qt::TextWordWrap) {
568 w = qMax(w-hextra-contentsMargin.width(), 0);
569 control->setTextWidth(w);
571 control->adjustSize();
574 control->setTextWidth(-1);
577 QSizeF controlSize = control->size();
578 br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
581 control->setTextWidth(oldTextWidth);
585 int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
587 flags |= Qt::TextShowMnemonic;
590 if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
591 flags |= Qt::TextHideMnemonic;
594 bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
596 w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
599 w -= (hextra + contentsMargin.width());
600 br = fm.boundingRect(0, 0, w ,2000, flags, text);
601 if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
602 br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
603 if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
604 br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
607 br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
610 const QSize contentsSize(br.width() + hextra, br.height() + vextra);
611 return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
925bool QLabel::event(QEvent *e)
928 QEvent::Type type = e->type();
930#ifndef QT_NO_SHORTCUT
931 if (type == QEvent::Shortcut) {
932 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
933 if (se->shortcutId() == d->shortcutId) {
934 QWidget *w = d->buddy;
936 return QFrame::event(e);
937 if (w->focusPolicy() != Qt::NoFocus)
938 w->setFocus(Qt::ShortcutFocusReason);
939#if QT_CONFIG(abstractbutton)
940 QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
941 if (button && !se->isAmbiguous())
942 button->animateClick();
945 window()->setAttribute(Qt::WA_KeyboardFocusChange);
950 if (type == QEvent::Resize) {
952 d->textLayoutDirty =
true;
953 }
else if (e->type() == QEvent::StyleChange
955 || e->type() == QEvent::MacSizeChange
958 d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
960 }
else if (type == QEvent::Polish) {
961 if (d->needTextControl())
962 d->ensureTextControl();
965 return QFrame::event(e);
970void QLabel::paintEvent(QPaintEvent *)
973 QStyle *style = QWidget::style();
974 QPainter painter(
this);
976 QRect cr = contentsRect();
977 cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
978 int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
979 : layoutDirection(), QFlag(d->align));
982 if (d->movie && !d->movie->currentPixmap().isNull()) {
983 if (d->scaledcontents)
984 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
986 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
990 if (d->isTextLabel) {
991 QRectF lr = d->layoutRect().toAlignedRect();
994#if QT_CONFIG(style_stylesheet)
995 if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
996 cssStyle->styleSheetPalette(
this, &opt, &opt.palette);
999#ifndef QT_NO_SHORTCUT
1000 const bool underline =
static_cast<
bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
1001 nullptr,
this,
nullptr));
1002 if (d->shortcutId != 0
1003 && underline != d->shortcutCursor.charFormat().fontUnderline()) {
1004 QTextCharFormat fmt;
1005 fmt.setFontUnderline(underline);
1006 d->shortcutCursor.mergeCharFormat(fmt);
1009 d->ensureTextLayouted();
1011 QAbstractTextDocumentLayout::PaintContext context;
1013 context.palette = opt.palette;
1015 if (foregroundRole() != QPalette::Text && isEnabled())
1016 context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
1019 painter.translate(lr.topLeft());
1020 painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
1021 d->control->setPalette(context.palette);
1022 d->control->drawContents(&painter, QRectF(),
this);
1025 int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
1026 : Qt::TextForceRightToLeft);
1027 if (d->hasShortcut) {
1028 flags |= Qt::TextShowMnemonic;
1029 if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt,
this))
1030 flags |= Qt::TextHideMnemonic;
1032 style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
1035#ifndef QT_NO_PICTURE
1037 QRect br = d->picture->boundingRect();
1038 int rw = br.width();
1039 int rh = br.height();
1040 if (d->scaledcontents) {
1042 painter.translate(cr.x(), cr.y());
1043 painter.scale((
double)cr.width()/rw, (
double)cr.height()/rh);
1044 painter.drawPicture(-br.x(), -br.y(), *d->picture);
1049 if (align & Qt::AlignVCenter)
1050 yo = (cr.height()-rh)/2;
1051 else if (align & Qt::AlignBottom)
1052 yo = cr.height()-rh;
1053 if (align & Qt::AlignRight)
1055 else if (align & Qt::AlignHCenter)
1056 xo = (cr.width()-rw)/2;
1057 painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
1061 if (d->icon && !d->icon->isNull()) {
1062 const qreal dpr = devicePixelRatio();
1063 const QSize size = d->scaledcontents ? cr.size() : d->pixmapSize;
1064 const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
1065 QPixmap pix = d->icon->pixmap(size, dpr, mode);
1071 if (pix.size() != size * dpr) {
1072 const QString key =
"qt_label_"_L1 % HexString<quint64>(pix.cacheKey())
1073 % HexString<quint8>(mode)
1074 % HexString<uint>(size.width())
1075 % HexString<uint>(size.height())
1076 % HexString<quint16>(qRound(dpr * 1000));
1077 if (!QPixmapCache::find(key, &pix)) {
1078 pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1079 pix.setDevicePixelRatio(dpr);
1085 QPixmapCache::insert(key, pix);
1090 style->drawItemPixmap(&painter, cr, align, pix);
1450QRect QLabelPrivate::documentRect()
const
1453 Q_ASSERT_X(isTextLabel,
"documentRect",
"document rect called for label that is not a text label!");
1454 QRect cr = q->contentsRect();
1455 cr.adjust(margin, margin, -margin, -margin);
1456 const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
1457 : q->layoutDirection(), QFlag(
this->align));
1459 if (m < 0 && q->frameWidth())
1460 m = q->fontMetrics().horizontalAdvance(u'x') / 2 - margin;
1462 if (align & Qt::AlignLeft)
1463 cr.setLeft(cr.left() + m);
1464 if (align & Qt::AlignRight)
1465 cr.setRight(cr.right() - m);
1466 if (align & Qt::AlignTop)
1467 cr.setTop(cr.top() + m);
1468 if (align & Qt::AlignBottom)
1469 cr.setBottom(cr.bottom() - m);
1544void QLabelPrivate::ensureTextControl()
const
1550 control =
new QWidgetTextControl(
const_cast<QLabel *>(q));
1551 control->document()->setUndoRedoEnabled(
false);
1552 control->document()->setDefaultFont(q->font());
1553 if (resourceProvider !=
nullptr)
1554 control->document()->setResourceProvider(resourceProvider);
1555 control->setTextInteractionFlags(textInteractionFlags);
1556 control->setOpenExternalLinks(openExternalLinks);
1557 control->setPalette(q->palette());
1558 control->setFocus(q->hasFocus());
1559 QObject::connect(control, &QWidgetTextControl::updateRequest,
1560 q, qOverload<>(&QLabel::update));
1561 QObject::connect(control, &QWidgetTextControl::linkActivated,
1562 q, &QLabel::linkActivated);
1563 QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
1564 this, &QLabelPrivate::linkHovered);
1565 textLayoutDirty =
true;