понедельник, 16 декабря 2013 г.

Qt. Как отследить перемещение мыши без нажатой кнопки

Qt. Как отследить перемещение мыши без нажатой кнопки?

Как отследить перемещения мыши на каком-бы то ни было виджете? Тут есть несколько вариантов:
  1. отслеживать событие.
  2. поставить фильтр.
  3. сделать захват мыши.
Сразу оговорюсь, пока вариант 3 мы рассматривать не будем (да и использовать его официальная документация не рекомендует).
Допустим, что отслеживать будем событие на форме.

Вариант 1.

Нам надо переопределить метод void mouseMoveEvent(QMouseEvent *). Поэтому просто в реализацию формы прописываем данный метод:

void MainWindow::mouseMoveEvent(QMouseEvent *me)
{
  qDebug() << tr("mouseEvent emitted: [x, y] = [%1, %2]"). 
              arg(me->x()).arg(me->y());
}

Но тут есть одно НО! Дело в том, что по умолчанию данное событие 
возникает только в случае нажатия одной из клавиш мыши. Чтобы можно 
было отследить движение мыши в "свободном полете", нам необходимо 
установить ее отслеживание с помощью метода 
 
void setMouseTracking(bool)
 
поэтому в конструкторе добавляем его:
 
this->setMouseTracking(true);
 
и такой же метод для виджета centralWidget() 
centralWidget()->setMouseTracking(true);
 
Получаем вот такой код:
 
#include "mainwindow.h"
#include "qmessagebox"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);

  this->setMouseTracking(true);
  centralWidget()->setMouseTracking(true);
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::mouseMoveEvent(QMouseEvent *me)
{
  qDebug() << tr("mouseEvent emitted: [x, y] = [%1, %2]")
               .arg(me->x()).arg(me->y());
}



Вариант 2:

а можно установить фильтр и тогда мы в одной функции сможем отслеживать сразу несколько событий. Делается это так:


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);




  this->setMouseTracking(true);
  centralWidget()->setMouseTracking(true);

 
 this->installEventFilter(this);
}
 

bool MainWindow::eventFilter(QObject* obj, QEvent* event)
{
  if (event->type() == QEvent::MouseMove)
    {
      QMouseEvent* me = static_cast<QMouseEvent*>(event);
      if (me)
        qDebug() << tr("mouseEvent emitted: [x, y] = [%1, %2]")
                       .arg(me->x()).arg(me->y());
      else
        qDebug() << tr("Стремное событие: %1");
    }
  return QMainWindow::eventFilter(obj, event);
}
 


В обоих случаях есть второе НО! событие не будет обрабатываться, 
если курсор мыши находится над дочерним элементом. Поэтому если необходимо 
"сквозное" отслеживание, то данный фильтр надо ставить для каждого 
дочернего элемента.

Комментариев нет:

Отправить комментарий

Буду рад Вашим комментариям...