Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to popup a widget when I hover a label?
Forum Updated to NodeBB v4.3 + New Features

How to popup a widget when I hover a label?

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 522 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mistgc
    wrote on last edited by mistgc
    #1

    There is a "volume label" that will pop up a vertical slider when I hover over it to control a media player's volume.

    Should I reimplement a new label inheriting "QLabel"?

    M 1 Reply Last reply
    0
    • M mistgc

      There is a "volume label" that will pop up a vertical slider when I hover over it to control a media player's volume.

      Should I reimplement a new label inheriting "QLabel"?

      M Offline
      M Offline
      mpergand
      wrote on last edited by
      #2

      @mistgc said in How to popup a widget when I hover a label?:

      Should I reimplement a new label inheriting "QLabel"?

      Or implement an event filter and intercept QEvent::ToolTip.

      1 Reply Last reply
      2
      • M Offline
        M Offline
        mistgc
        wrote on last edited by mistgc
        #3

        I finally completed it.
        .h file

        #ifndef GCPLAYER_GCVOLLABEL_H_
        #define GCPLAYER_GCVOLLABEL_H_
        
        #include <QLabel>
        #include <QSlider>
        #include <QWidget>
        
        class __GCVolLabel_innerSlider;
        class __GCVolLabel_innerLabel;
        
        class GCVolLabel : public QWidget {
          Q_OBJECT
         public:
          explicit GCVolLabel(QWidget *parent = nullptr);
        
          void setPopupFixedSize(const QSize &size);
          void setPopupFixedSize(const int w, const int h);
          void setText(const QString &text);
        
         protected:
          virtual void showPopupSlider();
          virtual void hidePopupSlider();
        
         private:
          QPoint getGlobalPos();
        
         private:
          bool m_isLabelHovered = false;
          bool m_isSliberHovered = false;
          __GCVolLabel_innerLabel *m_textLabel = nullptr;
          __GCVolLabel_innerSlider *m_popupSlider = nullptr;
        };
        
        class __GCVolLabel_innerLabel : public QLabel {
          Q_OBJECT
         public:
          __GCVolLabel_innerLabel(QWidget *parent = nullptr);
        
         protected:
          void enterEvent(QEnterEvent *ev);
          void leaveEvent(QEvent *ev);
        
         signals:
          void hoveredIn();
          void hoveredOut();
        };
        
        class __GCVolLabel_innerSlider : public QSlider {
          Q_OBJECT
         public:
          __GCVolLabel_innerSlider(QWidget *parent = nullptr);
        
         protected:
          void enterEvent(QEnterEvent *ev);
          void leaveEvent(QEvent *ev);
        
         signals:
          void hoveredIn();
          void hoveredOut();
        };
        
        #endif  // GCPLAYER_GCVOLLABEL_H_
        
        

        .cpp file

        #include <gcplayer/gcvollabel.h>
        #include <gcplayer/log.h>
        
        #include <QBrush>
        #include <QEvent>
        #include <QLabel>
        #include <QPainter>
        #include <QPen>
        #include <QSlider>
        #include <QTimer>
        
        GCVolLabel::GCVolLabel(QWidget *parent)
            : QWidget(parent),
              m_popupSlider(new __GCVolLabel_innerSlider(this)),
              m_textLabel(new __GCVolLabel_innerLabel(this)) {
          m_popupSlider->setWindowFlag(Qt::Popup);
          setPopupFixedSize(15, 70);
          m_popupSlider->hide();
        
          connect(m_popupSlider, &__GCVolLabel_innerSlider::hoveredIn, [&] {
            m_isSliberHovered = true;
            showPopupSlider();
          });
          connect(m_popupSlider, &__GCVolLabel_innerSlider::hoveredOut, [&] {
            m_isSliberHovered = false;
            hidePopupSlider();
          });
          connect(m_textLabel, &__GCVolLabel_innerLabel::hoveredIn, [&] {
            m_isSliberHovered = true;
            showPopupSlider();
          });
          connect(m_textLabel, &__GCVolLabel_innerLabel::hoveredOut, [&] {
            m_isSliberHovered = false;
            hidePopupSlider();
          });
        }
        
        void GCVolLabel::showPopupSlider() {
          if (m_isSliberHovered || m_isLabelHovered) {
            QPoint pos = getGlobalPos();
            pos = QPoint(pos.x(), pos.y() - m_popupSlider->height() - 5);
            m_popupSlider->move(pos);
            m_popupSlider->show();
          }
        }
        
        void GCVolLabel::hidePopupSlider() {
          // The Most Important Code
          QTimer::singleShot(600, [&] {
            if (!m_isSliberHovered && !m_isSliberHovered) {
              m_popupSlider->hide();
            }
          });
        }
        
        QPoint GCVolLabel::getGlobalPos() {
          QPoint pos = mapToGlobal(QPoint(0, 0));
          ldebug("GCVolLabel pos: (%d, %d)", pos.x(), pos.y());
          return pos;
        }
        
        void GCVolLabel::setPopupFixedSize(const QSize &size) {
          m_popupSlider->setFixedSize(size);
        }
        
        void GCVolLabel::setPopupFixedSize(const int w, const int h) {
          m_popupSlider->setFixedSize(w, h);
        }
        
        void GCVolLabel::setText(const QString &text) { m_textLabel->setText(text); }
        
        // __GCVolLabel_innerLabel
        
        __GCVolLabel_innerLabel::__GCVolLabel_innerLabel(QWidget *parent)
            : QLabel(parent) {}
        
        void __GCVolLabel_innerLabel::enterEvent(QEnterEvent *ev) { emit hoveredIn(); }
        
        void __GCVolLabel_innerLabel::leaveEvent(QEvent *ev) { emit hoveredOut(); }
        
        // __GCVolLabel_innerSlider
        
        __GCVolLabel_innerSlider::__GCVolLabel_innerSlider(QWidget *parent)
            : QSlider(parent) {}
        
        void __GCVolLabel_innerSlider::enterEvent(QEnterEvent *ev) { emit hoveredIn(); }
        
        void __GCVolLabel_innerSlider::leaveEvent(QEvent *ev) { emit hoveredOut(); }
        
        
        1 Reply Last reply
        0
        • C Offline
          C Offline
          CPPUIX
          wrote on last edited by
          #4

          Hi,

          I made a floating widget a while ago, it's a bit rough on the edges, but it could be helpful to your case.

          It just needs a parent and a trigger, it'll do the rest on its own.

          For a QLabel, you could use the linkActivated signal, since I believe clicking is a more controllable trigger compared to hovering, which could be triggered by mistake. But if you're determined on relying on mouse hover, you could use linkHovered instead.

          Here's an example:

          #include <QApplication>
          #include <QSlider>
          #include <QLabel>
          #include "mfloatwidget.h"
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
          
              //style the link to make it look like normal text
              //and provide whatever text for the actual link, it'll be enough to trigger linkActivated
              QLabel label("<a style=\"color: white; text-decoration:none;\" href=\"someText\">100%</a>");
              label.setAlignment(Qt::AlignCenter);
          
              MFloatWidget floatingWidget(&label);
              QSlider slider(Qt::Horizontal);
              //addWidget is a custom method to add widgets to the floating widget
              floatingWidget.addWidget(&slider);
          
              //clicking the label text will pop up the floating widget which contains the slider
              label.connect(&label, &QLabel::linkActivated, &floatingWidget, &QWidget::show);
          
              label.show();
          
              return a.exec();
          }
          

          floatingwidgetLabel.gif

          You can find some explanation about the custom widget on my blog: How to make a floating widget in Qt, and the link to the public repository if this is useful/useable.

          1 Reply Last reply
          1
          • M mistgc has marked this topic as solved on

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved