93QTipLabel::QTipLabel(
const QString &text,
const QPoint &pos, QWidget *w,
int msecDisplayTime)
94 : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget)
95#if QT_CONFIG(style_stylesheet)
96 , styleSheetParent(
nullptr)
103 setForegroundRole(QPalette::ToolTipText);
104 setBackgroundRole(QPalette::ToolTipBase);
105 setPalette(QToolTip::palette());
107 setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth,
nullptr,
this));
108 setFrameStyle(QFrame::NoFrame);
109 setAlignment(Qt::AlignLeft);
111 qApp->installEventFilter(
this);
112 setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity,
nullptr,
this) / 255.0);
113 setMouseTracking(
true);
114 reuseTip(text, msecDisplayTime, pos);
128void QTipLabel::reuseTip(
const QString &text,
int msecDisplayTime,
const QPoint &pos)
130#if QT_CONFIG(style_stylesheet)
131 if (styleSheetParent){
132 disconnect(styleSheetParent, &QWidget::destroyed,
133 this, &QTipLabel::styleSheetParentDestroyed);
134 styleSheetParent =
nullptr;
140 restartExpireTimer(msecDisplayTime);
143void QTipLabel::updateSize(
const QPoint &pos)
145 d_func()->setScreenForPoint(pos);
147 QFontMetrics fm(font());
150 if (fm.descent() == 2 && fm.ascent() >= 11)
152 setWordWrap(Qt::mightBeRichText(text()));
153 QSize sh = sizeHint();
154 const QScreen *screen = getTipScreen(pos,
this);
155 if (!wordWrap() && sh.width() > screen->geometry().width()) {
173void QTipLabel::resizeEvent(QResizeEvent *e)
175 QStyleHintReturnMask frameMask;
177 option.initFrom(
this);
178 if (style()->styleHint(QStyle::SH_ToolTip_Mask, &option,
this, &frameMask))
179 setMask(frameMask.region);
181 QLabel::resizeEvent(e);
184void QTipLabel::mouseMoveEvent(QMouseEvent *e)
186 if (!rect.isNull()) {
187 QPointF pos = e->globalPosition();
189 pos = widget->mapFromGlobal(pos);
190 if (!rect.contains(pos.toPoint()))
193 QLabel::mouseMoveEvent(e);
233bool QTipLabel::eventFilter(QObject *o, QEvent *e)
237 case QEvent::KeyPress:
238 case QEvent::KeyRelease: {
239 const int key =
static_cast<QKeyEvent *>(e)->key();
241 if (key < Qt::Key_Shift || key > Qt::Key_ScrollLock)
242 hideTipImmediately();
251#if defined (Q_OS_QNX) || defined (Q_OS_WASM)
253 case QEvent::WindowActivate:
254 case QEvent::FocusIn:
256 case QEvent::WindowDeactivate:
259 hideTipImmediately();
261 case QEvent::FocusOut:
262 if (
reinterpret_cast<QWindow*>(o) != windowHandle())
264 hideTipImmediately();
267 case QEvent::WindowActivate:
268 case QEvent::WindowDeactivate:
269 case QEvent::FocusIn:
270 case QEvent::FocusOut:
272 case QEvent::MouseButtonPress:
273 case QEvent::MouseButtonRelease:
274 case QEvent::MouseButtonDblClick:
276 hideTipImmediately();
279 case QEvent::MouseMove:
280 if (o == widget && !rect.isNull() && !rect.contains(
static_cast<QMouseEvent*>(e)->position().toPoint()))
296void QTipLabel::placeTip(
const QPoint &pos, QWidget *w)
298#if QT_CONFIG(style_stylesheet)
299 if (testAttribute(Qt::WA_StyleSheet) || (w && qt_styleSheet(w->style()))) {
301 QTipLabel::instance->setProperty(
"_q_stylesheet_parent", QVariant::fromValue(w));
303 QTipLabel::instance->setStyleSheet(
"/* */"_L1);
306 QTipLabel::instance->styleSheetParent = w;
308 connect(w, &QWidget::destroyed,
309 QTipLabel::instance, &QTipLabel::styleSheetParentDestroyed);
315 QTipLabel::instance->updateSize(pos);
320 const QScreen *screen = getTipScreen(pos, w);
322 if (
const QPlatformScreen *platformScreen = screen ? screen->handle() :
nullptr) {
323 QPlatformCursor *cursor = platformScreen->cursor();
325 const QSize nativeSize = cursor ? cursor->size() : QSize(16, 16);
326 const QSize cursorSize = QHighDpi::fromNativePixels(nativeSize,
328 QPoint offset(2, cursorSize.height());
330 if (cursorSize.height() > 2 *
this->height())
331 offset = QPoint(cursorSize.width() / 2, 0);
335#if QT_CONFIG(wayland)
338 if (
auto waylandWindow =
dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(windowHandle()->handle())) {
341 const QRect controlGeometry = QRect(p.x() - 4, p.y() - 24, 4, 24)
342 .translated(-w->window()->mapToGlobal(QPoint(0, 0)));
343 waylandWindow->setParentControlGeometry(controlGeometry);
344 waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ToolTip);
349 QRect screenRect = screen->geometry();
350 if (p.x() +
this->width() > screenRect.x() + screenRect.width())
351 p.rx() -= 4 +
this->width();
352 if (p.y() +
this->height() > screenRect.y() + screenRect.height())
353 p.ry() -= 24 +
this->height();
354 if (p.y() < screenRect.y())
355 p.setY(screenRect.y());
356 if (p.x() +
this->width() > screenRect.x() + screenRect.width())
357 p.setX(screenRect.x() + screenRect.width() -
this->width());
358 if (p.x() < screenRect.x())
359 p.setX(screenRect.x());
360 if (p.y() +
this->height() > screenRect.y() + screenRect.height())
361 p.setY(screenRect.y() + screenRect.height() -
this->height());
412void QToolTip::showText(
const QPoint &pos,
const QString &text, QWidget *w,
const QRect &rect,
int msecDisplayTime)
414 if (QTipLabel::instance && QTipLabel::instance->isVisible()) {
416 QTipLabel::instance->hideTip();
418 }
else if (!QTipLabel::instance->fadingOut) {
421 QPoint localPos = pos;
423 localPos = w->mapFromGlobal(pos);
424 if (QTipLabel::instance->tipChanged(localPos, text, w)){
425 QTipLabel::instance->reuseTip(text, msecDisplayTime, pos);
426 QTipLabel::instance->setTipRect(w, rect);
427 QTipLabel::instance->placeTip(pos, w);
433 if (!text.isEmpty()) {
434 QWidget *tipLabelParent = [w]() -> QWidget* {
444 new QTipLabel(text, pos, tipLabelParent, msecDisplayTime);
445 QWidgetPrivate::get(QTipLabel::instance)->setScreen(QTipLabel::getTipScreen(pos, w));
446 QTipLabel::instance->setTipRect(w, rect);
447 QTipLabel::instance->placeTip(pos, w);
448 QTipLabel::instance->setObjectName(
"qtooltip_label"_L1);
450#if QT_CONFIG(effects)
451 if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip))
452 qFadeEffect(QTipLabel::instance);
453 else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip))
454 qScrollEffect(QTipLabel::instance);
456 QTipLabel::instance->showNormal();
458 QTipLabel::instance->showNormal();