Qt: How to display a text consistently on the cursor, not depending on cursor position?

846 Views Asked by At

I want a text to be displayed persistently on the curser event when the cursor is moving, not depending on the cursor position. I used Qtooltip for this purpose. This is the code to show the text:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
// ...
}

bool Widget::event (QEvent *ev)
{
    if (event->type() == QEvent::ToolTip) {
         QHelpEvent *helpEvent = static_cast<QHelpEvent *>(ev);
         QToolTip::showText(helpEvent->globalPos(), "Something got it");

         return false;
     }
     return QWidget::event(ev);
}

But when I run this code the text is not displayed consistently and it shows up only sometimes, disappears while moving the cursor, and the whole window flickers.

1

There are 1 best solutions below

3
On

You can probably achieve what you want by intercepting mouse move events rather than the tool tip notifications...

class tooltip_event_filter: public QLabel {
  using super = QLabel;
public:
  tooltip_event_filter ()
    {
      setWindowFlags(windowFlags()
                     | Qt::BypassWindowManagerHint
                     | Qt::FramelessWindowHint
        );
    }
protected:
  virtual bool eventFilter (QObject *obj, QEvent *event) override
    {
      if (event->type() == QEvent::MouseMove) {

        /*
         * Note the QPoint(1, 0) offset here.  If we don't do that then the
         * subsequent call to qApp->widgetAt(QCursor::pos()) will return a
         * pointer to this widget itself.
         */
        move(QCursor::pos() + QPoint(1, 0));
        if (const auto *w = qApp->widgetAt(QCursor::pos())) {
          setText(QString("widget@%1").arg((qulonglong)w));
          show();
        } else {
          hide();
        }
      }
      return super::eventFilter(obj, event);
    }
};

Then install an instance of tooltip_event_filter on the application instance...

tooltip_event_filter tooltip_event_filter;
qApp->installEventFilter(&tooltip_event_filter);

The example shown simply displays the address of the widget under the mouse pointer as it's moved.