How to check if the mouse has really left the QWidget? - qt

Consider a QWidget window, what event is triggered when the mouse has left this window?
The window has QLineEdit fields on it and they have completers (QCompleter) for input suggestions. The actual goal is to make such an (open) completer disappear when the mouse leaves the window. This is mostly because in some environments, moving the mouse over a different window may focus that other window, but keyboard events are still sent to the QLineEdit field (even though its parent window isn't focused anymore), which is confusing.
I could implement QWidget::leaveEvent(QEvent *event) (in the window), find the currently shown completer popup and hide it, that closes the popup. But ironically, leaveEvent() is also triggered when the mouse is moved over that popup - hiding it (making it impossible to click on an item in that popup). I guess that makes sense because the popup is a different QWidget, even though the popup is indirectly owned by the window.
So how do I check if the mouse has actually left the QWidget window?

Reimplement QWidget::leaveEvent(QEvent *event) in your derived class but start by checking that rect().contains(mapFromGlobal(QCursor::pos())) is true.
If not, return without doing anything.
This should filter out all the events where the mouse is still over your widget.
Hope it helps!

Related

How can child widget capture the mouse event under such circumstance

I need to simulate drag and drop in Qt, but I'm facing a problem. Here is the simplified version of the problem:
here you can see the action I took. I pressed the mouse in the area of parent widget and moved it to a child widget, keeping pressing, I did not release the mouse until it is moved into the child Widget. However, I found that the child widget could not capture the mouse release event when I released the mouse. (Actually, I found it was not only mouse release event, but also any other mouse event which was supposed to happen when the mouse was in the child widget)
Could someone give me a simple solution to do this? Maybe It is because the widget structure in my project is quite complicated so there is something wrong stops the transfer of the mouse event.
Try to accept mouse release event in parent widget, calculate mouse position, compare to child widget, and notify child widget Qt - Determine absolute widget and cursor position.
Or use QDrag and QMimeData if you want to pass data.

How to lose selection focus of a QTextEdit?

I have a readonly QTextEdit. I'm able to select the text and copy it.
What I need to do: When the user is in selection mode(selecting text), if he leaves the area (with the left mouse button still holding) the widget must lose focus and selection focus must end too. When mouse exits out of bounds I want to be similar to mouse release. I tried to set this:
rootWidget->clearFocus();
rootWidget->close();
rootWidget->releaseMouse();
but even though visually the widget seems out of focus I still receive the TextEdit::mouseMoveEvent() of my widget.
I also tried to set focus to a dummy widget. The dummy widget gets focused but my textedit sitll gets mouseMoveEvent().
How can I lose focus of the widget completely without releasing the mouse button?
Thank you for any suggestion!
You can give the focus to something else using QWidget::setFocus(). you should probably clear the selection before changing focus.

Qt: Can mouse event handlers block one another?

I have a simple parent widget that reimplements mousePressEvent/mouseReleaseEvent. The parent's child widgets use enterEvent/leaveEvent. When I hover the mouse over the child widgets, leaveEvent/enterEvent executes, but when I click and hold the mouse, mousePressEvent executes, but enterEvent/leaveEvent goes silent (in other words, no click and drag). Any ideas about what could be causing this?
If you press and hold down the mouse button on a widget then that widget grabs mouse events until you release the button. This is not a special feature of Qt, you can find similar behaviour in every other GUI APIs I know.
Take a look at the relevant part of the Qt documentation:
QWidget / Events:
mousePressEvent() is called when a mouse button is pressed while the
mouse cursor is inside the widget, or when the widget has grabbed the
mouse using grabMouse(). Pressing the mouse without releasing it is
effectively the same as calling grabMouse().
void QWidget::grabMouse ():
Grabs the mouse input. This widget receives all mouse events until
releaseMouse() is called; other widgets get no mouse events at all.

Flex Air RollOver on inactive Native Window

I have a Native Window in Flex AIR. Let's say the window doesn't have a focus. It is inactive. Is it possible to find out when mouse is over such window? The window is always in front. I heard that it is possible by checking stage.mouseX in ENTER FRAME handler. But maybe there is a more elegant solution ?
I would look into using the MouseEvent.MOUSE_OVER event; which I would expect to fire whenever the mouse enters the window.
The only issue I see is that the NaiveWindow class does not document mouse events. So, the mouse event will most likely have to be dispatched from one of the children of the NativeWindow. You may try adding a a transparent image as the background, or something similar, and listen for the event on that image.
Not sure what you mean by you have a NativeWindow, but if you've extended spark.components.Window (which is the way you should be creating a window) and add a MouseEvent.MOUSE_MOVE listener to it then that will be triggered whenever the mouse is moving over the window, regardless of whether or not the window or application itself has focus.

How to force calling of QWidget::paintEvent() when its hovered by other window?

I have a problem:
I'm creating a widget which displays current date's day number. It's like a button, but it's not derived from QPushButton class. Just from QWidget. So I've reimplemented enterEvent(), leaveEvent(), mousePressEvent(), mouseReleaseEvent(). I do call update() inside these methods and widget has realistic button behavior (paintEvent() is reimplemented also).
But when I change system date and hover that widget with other window, my widget doesn't get paintEvent() and the old date is displayed. Only when I place mouse over it, widget repaints it's contents.
I guess there is a feature (like buffering) which paints old contents on hovering with other window to avoid unnecessary recalculations. But I need to disable it. Tried to set many attributes (the Qt::WidgetAttribute enum). But it doesn't work.
I think you should find a way to detect that the system time has changed and call update() when that happens. Any other method (like detecting the "hovering" of a window or waiting for a mouse event) will cause the update to occur too late.

Resources