530QSize QLabelPrivate::sizeForWidth(
int w)
const
533 if (q->minimumWidth() > 0)
534 w = qMax(w, q->minimumWidth());
535 QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
539 int hextra = 2 * margin;
541 QFontMetrics fm = q->fontMetrics();
543 if (icon && !icon->isNull()) {
544 br = QRect(QPoint(0, 0), pixmapSize);
546 }
else if (picture && !picture->isNull()) {
547 br = picture->boundingRect();
550 }
else if (movie && !movie->currentPixmap().isNull()) {
551 br = movie->currentPixmap().rect();
552 br.setSize(movie->currentPixmap().deviceIndependentSize().toSize());
554 }
else if (isTextLabel) {
555 int align = QStyle::visualAlignment(textDirection(), QFlag(
this->align));
559 if (m < 0 && q->frameWidth())
560 m = fm.horizontalAdvance(u'x') - margin*2;
562 if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
564 if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
569 ensureTextLayouted();
570 const qreal oldTextWidth = control->textWidth();
572 if (align & Qt::TextWordWrap) {
574 w = qMax(w-hextra-contentsMargin.width(), 0);
575 control->setTextWidth(w);
577 control->adjustSize();
580 control->setTextWidth(-1);
583 QSizeF controlSize = control->size();
584 br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
587 control->setTextWidth(oldTextWidth);
591 int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
593 flags |= Qt::TextShowMnemonic;
596 if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
597 flags |= Qt::TextHideMnemonic;
600 bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
602 w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
605 w -= (hextra + contentsMargin.width());
606 br = fm.boundingRect(0, 0, w ,2000, flags, text);
607 if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
608 br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
609 if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
610 br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
613 br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
616 const QSize contentsSize(br.width() + hextra, br.height() + vextra);
617 return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
931bool QLabel::event(QEvent *e)
934 QEvent::Type type = e->type();
936#ifndef QT_NO_SHORTCUT
937 if (type == QEvent::Shortcut) {
938 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
939 if (se->shortcutId() == d->shortcutId) {
940 QWidget *w = d->buddy;
942 return QFrame::event(e);
943 if (w->focusPolicy() != Qt::NoFocus)
944 w->setFocus(Qt::ShortcutFocusReason);
945#if QT_CONFIG(abstractbutton)
946 QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
947 if (button && !se->isAmbiguous())
948 button->animateClick();
951 window()->setAttribute(Qt::WA_KeyboardFocusChange);
956 if (type == QEvent::Resize) {
958 d->textLayoutDirty =
true;
959 }
else if (e->type() == QEvent::StyleChange
961 || e->type() == QEvent::MacSizeChange
964 d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
966 }
else if (type == QEvent::Polish) {
967 if (d->needTextControl())
968 d->ensureTextControl();
971 return QFrame::event(e);
976void QLabel::paintEvent(QPaintEvent *)
979 QStyle *style = QWidget::style();
980 QPainter painter(
this);
982 QRect cr = contentsRect();
983 cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
984 int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
985 : layoutDirection(), QFlag(d->align));
988 if (d->movie && !d->movie->currentPixmap().isNull()) {
989 if (d->scaledcontents)
990 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
992 style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
996 if (d->isTextLabel) {
997 QRectF lr = d->layoutRect().toAlignedRect();
1000#if QT_CONFIG(style_stylesheet)
1001 if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
1002 cssStyle->styleSheetPalette(
this, &opt, &opt.palette);
1005#ifndef QT_NO_SHORTCUT
1006 const bool underline =
static_cast<
bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
1007 nullptr,
this,
nullptr));
1008 if (d->shortcutId != 0
1009 && underline != d->shortcutCursor.charFormat().fontUnderline()) {
1010 QTextCharFormat fmt;
1011 fmt.setFontUnderline(underline);
1012 d->shortcutCursor.mergeCharFormat(fmt);
1015 d->ensureTextLayouted();
1017 QAbstractTextDocumentLayout::PaintContext context;
1019 context.palette = opt.palette;
1021 if (foregroundRole() != QPalette::Text && isEnabled())
1022 context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
1025 painter.translate(lr.topLeft());
1026 painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
1027 d->control->setPalette(context.palette);
1028 d->control->drawContents(&painter, QRectF(),
this);
1031 int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
1032 : Qt::TextForceRightToLeft);
1033 if (d->hasShortcut) {
1034 flags |= Qt::TextShowMnemonic;
1035 if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt,
this))
1036 flags |= Qt::TextHideMnemonic;
1038 style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
1041#ifndef QT_NO_PICTURE
1043 QRect br = d->picture->boundingRect();
1044 int rw = br.width();
1045 int rh = br.height();
1046 if (d->scaledcontents) {
1048 painter.translate(cr.x(), cr.y());
1049 painter.scale((
double)cr.width()/rw, (
double)cr.height()/rh);
1050 painter.drawPicture(-br.x(), -br.y(), *d->picture);
1055 if (align & Qt::AlignVCenter)
1056 yo = (cr.height()-rh)/2;
1057 else if (align & Qt::AlignBottom)
1058 yo = cr.height()-rh;
1059 if (align & Qt::AlignRight)
1061 else if (align & Qt::AlignHCenter)
1062 xo = (cr.width()-rw)/2;
1063 painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
1067 if (d->icon && !d->icon->isNull()) {
1068 const qreal dpr = devicePixelRatio();
1069 const QSize size = d->scaledcontents ? cr.size() : d->pixmapSize;
1070 const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled;
1071 QPixmap pix = d->icon->pixmap(size, dpr, mode);
1077 if (pix.size() != size * dpr) {
1078 const QString key =
"qt_label_"_L1 % HexString<quint64>(pix.cacheKey())
1079 % HexString<quint8>(mode)
1080 % HexString<uint>(size.width())
1081 % HexString<uint>(size.height())
1082 % HexString<quint16>(qRound(dpr * 1000));
1083 if (!QPixmapCache::find(key, &pix)) {
1084 pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1085 pix.setDevicePixelRatio(dpr);
1091 QPixmapCache::insert(key, pix);
1096 style->drawItemPixmap(&painter, cr, align, pix);
1456QRect QLabelPrivate::documentRect()
const
1459 Q_ASSERT_X(isTextLabel,
"documentRect",
"document rect called for label that is not a text label!");
1460 QRect cr = q->contentsRect();
1461 cr.adjust(margin, margin, -margin, -margin);
1462 const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
1463 : q->layoutDirection(), QFlag(
this->align));
1465 if (m < 0 && q->frameWidth())
1466 m = q->fontMetrics().horizontalAdvance(u'x') / 2 - margin;
1468 if (align & Qt::AlignLeft)
1469 cr.setLeft(cr.left() + m);
1470 if (align & Qt::AlignRight)
1471 cr.setRight(cr.right() - m);
1472 if (align & Qt::AlignTop)
1473 cr.setTop(cr.top() + m);
1474 if (align & Qt::AlignBottom)
1475 cr.setBottom(cr.bottom() - m);
1550void QLabelPrivate::ensureTextControl()
const
1556 control =
new QWidgetTextControl(
const_cast<QLabel *>(q));
1557 control->document()->setUndoRedoEnabled(
false);
1558 control->document()->setDefaultFont(q->font());
1559 if (resourceProvider !=
nullptr)
1560 control->document()->setResourceProvider(resourceProvider);
1561 control->setTextInteractionFlags(textInteractionFlags);
1562 control->setOpenExternalLinks(openExternalLinks);
1563 control->setPalette(q->palette());
1564 control->setFocus(q->hasFocus());
1565 QObject::connect(control, &QWidgetTextControl::updateRequest,
1566 q, qOverload<>(&QLabel::update));
1567 QObject::connect(control, &QWidgetTextControl::linkActivated,
1568 q, &QLabel::linkActivated);
1569 QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
1570 this, &QLabelPrivate::linkHovered);
1571 textLayoutDirty =
true;