earth
earth

Reputation: 955

Moving/dragging a FramelessWindow? [Qt]

I have a very simple application that is Windowless (setWindowFlags(Qt::FramelessWindowHint);) and has one QPushButton.

enter image description here

I made the entire window draggable with the following code:

void myApp::mousePressEvent(QMouseEvent* event){
  m_nMouseClick_X_Coordinate = event->x();
  m_nMouseClick_Y_Coordinate = event->y();
  qDebug() << m_nMouseClick_X_Coordinate;
  qDebug() << m_nMouseClick_Y_Coordinate;
}

void myApp::mouseMoveEvent(QMouseEvent* event){
  move(event->globalX()-m_nMouseClick_X_Coordinate,event->globalY()-m_nMouseClick_Y_Coordinate);
  qDebug() << event->globalX();
  qDebug() << event->globalY();
}

The window gets dragged fine when I drag anywhere except on the QPushButton. If I start the drag on the button (click and hold), the qDebug outputs nothing. When I start to drag it, the window moves, but the drag origin jumps to the coordinates of wherever the previous drag started and the cursor also jumps to the position of the last drag. Is there a way to make it so that starting the drag on the QPushButton doesn't cause this behavior? The coordinates don't seem to get captured when the QPushButton is the beginning of the drag.

Thanks in advance.


EDIT: See the response by @Hi I'm Frogatto below. It gives a good outline of how to do implement this and get it working. I wound up installing the event filter to the pushbutton in the constructor:

ui->pushButton->installEventFilter(this);

Then I created my eventfilter:

bool myApp::eventFilter(QObject *obj, QEvent *event)
{
  if (obj == ui->pushButton && event->type()==QMouseEvent::MouseButtonPress){
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
//    m_nMouseClick_X_Coordinate = mouseEvent->x() + 100;
//    m_nMouseClick_Y_Coordinate = mouseEvent->y() + 90;
    absPosX = ui->pushButton->mapToParent(QPoint(0,0)).x();
    absPosY = ui->pushButton->mapToParent(QPoint(0,0)).y();
    m_nMouseClick_X_Coordinate = mouseEvent->x() + absPosX;
    m_nMouseClick_Y_Coordinate = mouseEvent->y() + absPosY;
    return true;
  }
  return false;
}

Note that I commented out the section where I update the two variables with hard values. I didn't want to have to hard code the location of the button every time, so I defined some absolute positions of the button using mapToParent.

Upvotes: 1

Views: 1782

Answers (1)

frogatto
frogatto

Reputation: 29285

It appears that the QPushButton absorbs the press event and does not deliver it to its parent widget. So in this case the parent widget will not get notified of that mouse press event. A simple solution to this problem is using Qt event filters. You could install an event filter on that QPushButton which could be thought of as an entry point for all events to this button.

Therefore, the workflow is as follows:

  1. User presses the mouse click on the button.
  2. Mouse press event is delivered to our event filter.
  3. Our event filter updates m_nMouseClick_X_Coordinate and m_nMouseClick_Y_Coordinate variables. And then redirects the event to the button.
  4. The button receives the event...

Now, we should do:

  • Define our event filter class.
  • And implement its filter method.

I will leave the rest to you as an exercise. :)

Upvotes: 2

Related Questions