-1

When an object of QLabel subclass is active, how can one find if the mouse pointer is on the label and get its position if it is?

QWidegt::event() can check the event type of QEvent::WindowActivate, but it provides no information about mouse pointer position.


I then tried the following code, which verifies itself that both focusInEvent and focusOutEvent can happen. However, I still cannot get the mouse pointer position. Maybe I am missing the part of "bind enable/disable of mouse tracking to focus in and out events", or something else.

#include "mainwindow.h"

#include <QApplication>
#include <QtWidgets>
#include <QtCore>

class MyLabel : public QLabel
{
public:
    MyLabel(QWidget*parent = nullptr) : QLabel(parent)
    {
        setMouseTracking(true);
        setFocusPolicy(Qt::FocusPolicy::StrongFocus);
    }

protected:
    virtual void focusInEvent(QFocusEvent *ev) override
    {
        (void)ev;
        this->setText(__PRETTY_FUNCTION__);
    }
    virtual void focusOutEvent(QFocusEvent *ev) override
    {
        (void)ev;
        this->setText(__PRETTY_FUNCTION__);
    }

    virtual void mouseMoveEvent(QMouseEvent *ev) override
    {
        this->setText(QString::number(ev->pos().x()) +", " +QString::number(ev->pos().y()));

        QLabel::mouseMoveEvent(ev);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyLabel w;
    w.setFixedSize(400, 300);
    w.show();
    return a.exec();
}
5
  • 1
    You could activate mouse tracking via setMouseTracking(true) for your QLabel subclass and override mouseMoveEvent(QMouseEvent *ev) to get informed about mouse movement on your label widget and get mouse position. On top of that you could bind enable/disable of mouse tracking to focus in and out events. Therefore it's necessary to override focusInEvent(QFocusEvent *ev) and focusOutEvent(QFocusEvent *ev) and set focus policy accordingly. Commented Feb 16, 2021 at 22:26
  • I used the source code you provided by update and it works. I can see the changing x and y position label text if i move the mouse on it. It also works without using/overriding the focus events. Commented Feb 17, 2021 at 10:08
  • That's consistent with what I see. However, my intension is to find mouse pointer position when the label gets the focus but without moving the mouse (sorry I didn't express that clearly) - I am trying to let the user compare two datasets which are plotted as heatmaps in labels, and when the user uses Ctrl+Tab to switch between those two labels (sub windows in QMdiArea), the value under the mouse should be shown in tooltips, if it is possible to get the mouse pointer position without moving mouse. Commented Feb 17, 2021 at 16:34
  • 1
    You could use static function QCursor::pos() to get current cursor position if widget gets focus. After that get global position of your label widget upper left corner using mapToGlobal(QPoint(0,0)) and lower right corner using mapToGlobal(QPoint(width(), height())). Finally check if cursor position is inside your label widgets rectangle and run an action (e.g. show tooltip). Commented Feb 17, 2021 at 18:28
  • This works. Thanks a lot. Could you possibly summarize what you said as an answer? That way, I can accept it as the answer, and it might be helpful to others. Commented Feb 17, 2021 at 19:24

2 Answers 2

1

To check if mouse cursor is on custom widget derived from QLabel at time when it gets focus just override focusInEvent() and handle mouse cursor position check there.

MyLabel.h

class MyLabel: public QLabel
{
    Q_OBJECT

public:
    MyLabel(QWidget *parent = nullptr);
    ~MyLabel();

protected:
    virtual void focusInEvent(QFocusEvent *event) override;
};

MyLabel.cpp

MyLabel::MyLabel(QWidget *parent)
    : QLabel(parent)
{
    setFocusPolicy(Qt::StrongFocus);
}

MyLabel::~MyLabel()
{
}

void MyLabel::focusInEvent(QFocusEvent *event)
{
    if (event) {
        const QPoint cursorPos = QCursor::pos();
        if (rect().contains(mapFromGlobal(cursorPos))) {
            // TODO: Add desired action
        }
        QLabel::focusInEvent(event);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

This answer was extracted from the question post.


Based on Mathias Schmid, the final solution is to use the static function QCursor::pos() in focusInEvent().

#include "mainwindow.h"

#include <QApplication>
#include <QtWidgets>
#include <QtCore>
#include <QCursor>

class MyLabel : public QLabel
{
public:
    MyLabel(QWidget*parent = nullptr) : QLabel(parent)
    {
        setMouseTracking(true);
        setFocusPolicy(Qt::FocusPolicy::StrongFocus);
    }

protected:
    virtual void focusInEvent(QFocusEvent *ev) override
    {
        (void)ev;
        QPoint pos = QCursor::pos();
        QString msg = QString(__PRETTY_FUNCTION__) + ": \n" +  QString::number(pos.x()) + ", " + QString::number(pos.y());
        QPoint posLocal = this->mapFromGlobal(pos);
        if(this->rect().contains(posLocal))
            msg += "\nLocal pos: " + QString::number(posLocal.x()) + ", " + QString::number(posLocal.y());

        this->setText(msg);

        QLabel::focusInEvent(ev);
    }
    virtual void focusOutEvent(QFocusEvent *ev) override
    {
        (void)ev;
        this->setText(QString(__PRETTY_FUNCTION__));

        QLabel::focusOutEvent(ev);
    }

    virtual void mouseMoveEvent(QMouseEvent *ev) override
    {
        this->setText(QString::number(ev->pos().x()) +", " +QString::number(ev->pos().y()));

        QLabel::mouseMoveEvent(ev);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyLabel w;
    w.setFixedSize(450, 300);
    w.show();
    return a.exec();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.