ToolTip.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "ToolTip.h"
  2. #include "Common/StyleSheet.h"
  3. #include <QApplication>
  4. #include <QScreen>
  5. #include <QGraphicsDropShadowEffect>
  6. #include <QHBoxLayout>
  7. #include <QTimer>
  8. #include <QEvent>
  9. ToolTip::ToolTip(const QString &text, QWidget *parent)
  10. : QFrame(parent),
  11. m_text(text),
  12. m_duration(1000),
  13. m_container(new QFrame(this)),
  14. m_timer(new QTimer(this)),
  15. m_label(new QLabel(text, this))
  16. {
  17. QHBoxLayout *mainLayout = new QHBoxLayout();
  18. setLayout(mainLayout);
  19. QHBoxLayout *containerLayout = new QHBoxLayout(m_container);
  20. mainLayout->setContentsMargins(12, 8, 12, 12);
  21. mainLayout->addWidget(m_container);
  22. containerLayout->addWidget(m_label);
  23. containerLayout->setContentsMargins(8, 6, 8, 6);
  24. // add shadow
  25. QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(this);
  26. shadowEffect->setBlurRadius(25);
  27. shadowEffect->setColor(QColor(0, 0, 0, 60));
  28. shadowEffect->setOffset(0, 5);
  29. m_container->setGraphicsEffect(shadowEffect);
  30. m_timer->setSingleShot(true);
  31. connect(m_timer, &QTimer::timeout, this, &ToolTip::hide);
  32. // set style
  33. setAttribute(Qt::WA_TransparentForMouseEvents);
  34. setAttribute(Qt::WA_TranslucentBackground);
  35. setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
  36. setQss();
  37. }
  38. void ToolTip::setQss()
  39. {
  40. m_container->setObjectName("container");
  41. m_label->setObjectName("contentLabel");
  42. FluentStyleSheet::apply("TOOL_TIP", this);
  43. m_label->adjustSize();
  44. adjustSize();
  45. }
  46. QString ToolTip::text() const
  47. {
  48. return m_text;
  49. }
  50. /// set text on tooltip
  51. void ToolTip::setText(const QString &text)
  52. {
  53. m_text = text;
  54. m_label->setText(text);
  55. m_container->adjustSize();
  56. adjustSize();
  57. }
  58. int ToolTip::duration() const
  59. {
  60. return m_duration;
  61. }
  62. /// set tooltip duration in milliseconds
  63. void ToolTip::setDuration(int duration)
  64. {
  65. m_duration = duration;
  66. }
  67. /**
  68. * @brief adjust the position of tooltip relative to widget
  69. * @param pos: global position of widget
  70. * @param size: size of widget
  71. */
  72. void ToolTip::adjustPos(const QPoint &pos, const QSize &size)
  73. {
  74. int x = pos.x() + size.width() / 2 - this->width() / 2;
  75. int y = pos.y() - this->height();
  76. // adjust postion to prevent tooltips from appearing outside the screen
  77. QRect rect = QApplication::screenAt(QCursor::pos())->availableGeometry();
  78. if (QCursor::pos().x() >= 0) {
  79. x = qMin(qMax(0, x), rect.width() - this->width() - 4);
  80. } else {
  81. x = qMin(x, rect.width() - this->width() - 4);
  82. }
  83. y = qMin(qMax(0, y), rect.height() - this->height() - 4);
  84. this->move(x, y);
  85. }
  86. void ToolTip::showEvent(QShowEvent *event)
  87. {
  88. m_timer->stop();
  89. m_timer->start(m_duration);
  90. QFrame::showEvent(event);
  91. }
  92. void ToolTip::hideEvent(QHideEvent *event)
  93. {
  94. m_timer->stop();
  95. QFrame::hideEvent(event);
  96. }
  97. ToolTipFilter::ToolTipFilter(QWidget *parent, int showDelay)
  98. : QObject(parent), m_isEnter(false), m_toolTip(nullptr), m_tooltipDelay(showDelay), m_timer(new QTimer(this))
  99. {
  100. }
  101. void ToolTipFilter::hideToolTip()
  102. {
  103. m_isEnter = false;
  104. if (m_toolTip) {
  105. m_toolTip->hide();
  106. }
  107. }
  108. void ToolTipFilter::showToolTip()
  109. {
  110. if (!m_isEnter) {
  111. return;
  112. }
  113. QWidget *parent = qobject_cast<QWidget *>(this->parent());
  114. m_toolTip->setText(parent->toolTip());
  115. m_toolTip->adjustPos(parent->mapToGlobal(QPoint()), parent->size());
  116. m_toolTip->show();
  117. }
  118. void ToolTipFilter::setTooltipDelay(int delay)
  119. {
  120. m_tooltipDelay = delay;
  121. }
  122. bool ToolTipFilter::eventFilter(QObject *watched, QEvent *event)
  123. {
  124. if (event->type() == QEvent::ToolTip) {
  125. return true;
  126. } else if ((event->type() == QEvent::Hide) || (event->type() == QEvent::Leave)) {
  127. hideToolTip();
  128. } else if (event->type() == QEvent::Enter) {
  129. m_isEnter = true;
  130. QWidget *parent = qobject_cast<QWidget *>(this->parent());
  131. if (parent->isWidgetType() && !parent->toolTip().isEmpty()) {
  132. if (!m_toolTip) {
  133. m_toolTip = new ToolTip(parent->toolTip(), parent->window());
  134. }
  135. int t = 1000;
  136. if (parent->toolTipDuration() > 0) {
  137. t = parent->toolTipDuration();
  138. }
  139. m_toolTip->setDuration(t);
  140. // show the tool tip after delay
  141. QTimer::singleShot(m_tooltipDelay, this, &ToolTipFilter::showToolTip);
  142. }
  143. }
  144. return QObject::eventFilter(watched, event);
  145. }