Qt mouse leave event while button is pressed - c++

I need to detect if the mouse pointer leaves my custom widget even if a mouse button is pressed.
According to this post, Qt does not cause a leaveEvent in case a button is pressed, at least not in version 4.4. I am working with 4.7.3, but still do not get a leaveEvent in the described case. I also tried with the various drag-related events, but no luck. Does anyone have an idea how to deal with this?

Actually there is an even better option than using the mouse events of the parent widget: You can implement the mouseMoveEvent function of the child widget and get the QMouseEvent::pos() position which is relative to the top left corner of the widget. That means, if you know the size of the widget (use for example QWidget::rect()), you can compute within the widget if the mouse pointer is still on the widget or not without having to change the parent widget.

Well, I did something similar to #gregseth.
Write your own MouseLeaveEvent that is invoked from MouseMoveEvent
when the mouse's position is outside of the widget's boundary.
As Qt's documentation says "Mouse move events will occur only when a mouse button is pressed down"

I got the same problem. The only workaround I found is to manage the mouseMove event of the parent widget, and to check if the position of the cursor is inside or outside the boundaries of the widget you want the event on.

Related

Qt: Ignore MouseButtonRelease events when widget is hidden

The Documentation for QWidget says this:
mouseReleaseEvent() is called when a mouse button is released. A
widget receives mouse release events when it has received the
corresponding mouse press event. This means that if the user presses
the mouse inside your widget, then drags the mouse somewhere else
before releasing the mouse button, your widget receives the release
event. There is one exception: if a popup menu appears while the mouse
button is held down, this popup immediately steals the mouse events.
It also says this:
If you create new widgets in the mousePressEvent() the
mouseReleaseEvent() may not end up where you expect, depending on the
underlying window system (or X11 window manager), the widgets'
location and maybe more
In my programme, the is a context where the user can change the current visible widget by pressing Enter. If they click and hold on a toolbar button and press enter while the mouse is still pressed, they can send the mouse release event to the now hidden widget. This is a problem as the actions in the toolbar of the now hidden page, relate to a state which has been deinitialised when the active widget was changed.
The desired behaviour would be for the changing of active widget to somehow 'cancel' or 'release' the old widget's claim to the coming mouse release event even though it (or one of its children) received the corresponding mouse press event, and for the action in the toolbar not to be triggered.
Is there any way to do this? Or does anyone have any guidance on what I might be looking for?
Thanks
One options is by creating eventFilter function (either in widget itself (if your own) or parent widget), installing it with installEventFilter and then checking for mouse release event type and only accept the event if widget's isVisible() returns true.
Another option (in case you have your own Qt based widget class) is to override mouseReleaseEvent and do the same visibility check in there.

How to enable mouse tracking on a QWindow

I'm using a QWindow (Not a QMainWindow) with OpenGL. I need to use a QWindow to correctly control the OGL context.
I'm trying to follow the Scribble example to implement something similar to panning, but I can't find a paradigmatic way to trigger the mouseMoveEvent().
How can I get a "tooltip" effect where mouseMoveEvent() is constantly triggered, similar to setMouseTracking()?
It works fine for me. I created a test program with a MainWindow that inherits QWindow instead of QMainWindow, and handles the mouse move event to print the cursor position:
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
qDebug("%d, %d", e->pos().x(), e->pos().y());
}
It works, as I move the mouse I get events even without pressing any mouse buttons.
If mouse tracking is disabled (the default), the widget only receives mouse move events when at least one mouse button is pressed while the mouse is being moved.
you can call hasMouseTracking() or setMouseTracking() to control mouse's tracing state.
When mouse is traced, mouseMoveEvent() will be called, and you can reimpletment mouseMoveEven() to acquire mouse position, just as #sashoalm did.
BTW, mouse event is always transfered to your app, but filtered by it's parent or itself. You can reimpletment eventFilter() to code your own filter.

QT : leaveEvent - Checking if the cursor is in region of a widget?

I currently have a class that inherits from QLabel this class implements the methods mouseMoveEvent and leaveEvent. When the mouse is over this widget a dialog box is displayed. However the dialog box only disappears if a mouse click occurs elsewhere. I want the dialog box to disappear when the mouse moves out of the reqion of this widget. I therefore thought about using the leaveEvent method which would call dialog.hide(). My question is how can I determine if the mouse cursor is in the region of a widget ?
Have a look at Qt - Determine absolute widget and cursor position. Two ways are explained there.. using coordinates and using QWidget::underMouse().

A scrollbar event when scrolling?

I need an event for detecting if an user has moved the scrollbar position to another one.
In other words, if the user does scroll up/down, would it be possible to catch a signal so I can know the scroll has been changed its position?
I think it's not important, but the scrollbar I refer to is inside a QGraphicsView.
Regards.
Edit:
QGraphicsView is for displaying items in the screen, and if those items are too big it shows the scrollbars I refer to. What I need is to know when the user changes the position of those scrollbars.
Sliders have a sliderMoved(int value) signal, where value is the new position of slider.
If you need to get notified when the scroll bar position is changed, you need to subclass the QGraphicsView and reimplement the QWidget::mouseMoveEvent(QMouseEvent*). For this you also need to enable mouse tracking. Here is Qt 4.7 QGraphicsView reference.

mouse over transparency in Qt

I am trying to create an app in Qt/C++ with Qt4.5 and want the any active windows to change opacity on a mouseover event...
As i understand it, there is no explicit mouseover event in Qt.
However, I got rudimentary functioning by reimplementing QWidget's mousemoveevent() in the class that declares my mainwindow. But the mainwindow's mousemoveevent is not called whenever the mouse travels over any of the group boxes i have created in there (understandbly since QGroupbox has its own reimplementation of mousemoveevent).
So as a cheap work around, I am still using the mousemoveevent of my mainwindow but a query the global mouse position and based on the (x,y) position of the mainwindow (obtained through ->pos()) and the window size (-> size -> rHeight and rWidth), I check if the mouse is within the bounds of the area of the mainwindow and change the opacity thus.
This has had very limited success. The right border works fine, the the left changes opacity 4 pixels early. The top does not work (presumably because the mouse goes through the menubar and title bar) and the bottom changes way too early.
I thought of creating an empty container QWidget class and then place all the rest in there, but i felt that it would still not solve the big issue of the base widget not receiving the mousemoveevent if it has already been implemented in a child widget.
Please suggest any corrections/errors I have made in my method or any alternate methods to achieve this.
p.s. I doubt this matters, but I am working Qt Creator IDE, not Qt integration into VS2008 (it's the same classes anyways - different compiler though, mingw)
Installing event filters for each of your child widgets might do the trick. This will allow your main window to receive child events such as the ones from you group boxes. You can find example code here.
You may be interested in Event filters. QObject proves a way to intercept all events zipping around your application.
http://doc.trolltech.com/4.5/eventsandfilters.html#event-filters
If I understand what you are attempting to do, I would reimplement the widget's enterEvent() and leaveEvent(). The mouse enter event would trigger the fade-in and the leaveEvent would trigger the fade-out.
EDIT: After re-reading several times, I'm still not sure what you are trying to accomplish. Sorry if my suggestion doesn't help. :-)