I’m using Qt 4.8.3 on X11.
I need to know when the user ends with dragging a window around the screen, this in order to read the final position and eventually start an animation to adjust the window position to an “allowed” one.
I noticed that the QWidget::moveEvent is called for each small movement, but this is very unconvenient because I must perform position checking (and eventually start the animation) only when the user releases the mouse button and the movement is completely finished.
This is the real problem: it seems that there is no way to detect the mouse release event (or to get the mouse buttons status) when the user clicks on the titlebar, since it is controlled by the OS and not by Qt.
I tried also with the QWidget::x11event(XEvent* e)… but the events are collected only inside the window, not the title bar, as well.
Does someone know a way to achieve this?
I suspect that I will have to reimplement the titlebar myself… too bad…
Realizing this is a very old question, it is the first hit that comes up when you try "Qt detecting the end of a window move event". So, I thought I'd add a solution that works well with the current (as of this writing) release of Qt, 5.12.3.
You can set up a small state machine that provides the boundaries for knowing when a top-level window's position has been altered using a QObject::eventFilter(). In Qt 5.12.x, you will receive a QEvent::NonClientAreaMouseButtonPress event when the mouse goes down in the non-client area of your window (e.g., the title bar), a subsequent QEvent::Move event when the window position changes (if at all), and then a final QEvent::NonClientAreaMouseButtonRelease event when the mouse button is released.
Knowing this sequence, and using a persistent Boolean state flag (user_moved_window) to know that the position actually changed, would give you the following code snippet within your QObject::eventFilter() method:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
QEvent::Type event_type = event->type();
[...]
else if(event_type == QEvent::NonClientAreaMouseButtonPress)
user_moved_window = false;
else if(event_type == QEvent::Move && isVisible())
user_moved_window = true;
else if(event_type == QEvent::NonClientAreaMouseButtonRelease)
{
if(user_moved_window)
{
// do what you need to do to here to respond to
// the end of the reposition event...
user_moved_window = false;
}
}
[...]
return MainWindow::eventFilter(obj, event);
}
You might need to add some additional checks depending on your situation--e.g., to make sure the obj for the event is actually the main window--but this example works well for my production code using Qt 5.12.3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With