Catch 'DoubleMouseClick' inside 'mouseMoveEvent' QtabWidget
-
@Narutoblaze Sorry, but what you posted makes no sense. Moving a mouse and pressing its buttons are two different events. You can't "catch a click inside move". What does that even mean?
e->buttons()
returns the state of the buttons when given event occurs. When you check it within mouse move handler it reports the state of the buttons at the time the mouse was moved. It doesn't report any clicks.A click is a press and release over the same widget. A double click is press, release, press, release over the same widget with a small time window. When that happens a widget gets these event handlers in order:
mousePressEvent
mouseReleaseEvent
mousePressEvent
mouseDoubleClickEvent
mouseReleaseEventso if you want to handle double click manually then override
mouseDoubleClickEvent
, notmouseMoveEvent
, which happens when the mouse is moved over a widget. As @giusdbg mentioned, in case of QTabWidget, you can also connect to thetabBarDoubleClicked
signal it emits.Also, important thing to remember is, when you do override these events, you should either call the base implementation or explicitly call
e->accept()
ore->ignore()
to actually handle the event. Not doing this leaves the widget in inconsistent state if it does anything special in the base implementation, which is likely in case of a tab widget. -
@Chris-Kawa @Christian-Ehrlicher @giusdbg I apologize for not providing full context of what i have done and want to do further.
This is what i am doing :
void CustomTab::mouseMoveEvent(QMouseEvent *e) { // IF Not Mouse Double CLicked // if(e->buttons() != Qt::MouseDoubleClicked) // return; if (!tabBar()->tabRect(tabBar()->tabAt(e->pos())).contains(e->pos())) return; QTabBar *tabbar = tabBar(); QRect tabrect = tabbar->tabRect(tabbar->tabAt(e->pos())); QPixmap pix = QPixmap(tabrect.size()); tabbar->render(&pix, QPoint(), QRegion(tabrect)); QCursor cursor = QCursor(Qt::OpenHandCursor); QDrag drag = QDrag(tabbar); drag.setHotSpot(e->pos() - tabbar->mapFromGlobal(mapToGlobal(e->pos()))); drag.setDragCursor(cursor.pixmap(), Qt::MoveAction); drag.setMimeData(new QMimeData()); drag.setPixmap(pix); drag.exec(Qt::MoveAction); }
I am making use of mouseMoveEvent and i want to drag the tabbar only if double clicked when moving and as @Chris-Kawa said it only tells the state i was able to catch Qt::RightButton but could not catch Qt::LeftButton even i was clicking while moving.
-
@Narutoblaze
Like @Chris-Kawa said I don't understand how you would double-click while moving. And you are doing a drag operation, so won't any mouse release end it anyway?Are you sure you don't mean something like you want a double-click to start moving the tab bar, not double-click when moving?
-
@Narutoblaze
Well that is a totally different question!By the time you are in
mouseMoveEvent()
, and about to start your drag, it's too late to tell whether you invoked it via a double-click. And you cannot tell from mouse button state, that will tell you it's left or right button, and modifier keys, but not what clicking happened.From @Chris-Kawa's order of events, either start your drag in
mouseDoubleClickEvent()
or handle that to note the time and inmouseMoveEvent()
compare time now against that (e.g. use a classQElapsedTimer
) to see whether the double-click happened "recently" enough that you want to allow drag. -
@Narutoblaze First of all it's very weird what you're doing. A drag operation means you're dragging something i.e. grab it and move it while holding it, so starting a drag on double click (remember, double click is press, release, press, release) is very uncommon and not user friendly.
But anyway, assuming there's some deeper reason for doing such a thing, you're doing it wrong. If you really want to start a drag after the double click then no button will be pressed at the time of move. Yet again - double click is press, release, press, release. So to do drag on double click you would override
mouseDoubleClickEvent
. If you want to start the drag on double click that's where you do your drag code. If you want to do drag on move after double click then do as @JonB said - note the time (also mouse pos and some bool to indicate that a double click happened) and in the move event check if the time difference is under a limit and you moved far enough from the click place and then start your drag code.Important things to note:
- Since you want to get a move after a double click no mouse button will be pressed at that time. Widgets by default don't get mouse move events when no button is pressed. To get those events you need to enable mouse tracking on your widget.
- The minimum distance to start a drag is platform specific and you should use QStyleHints::startDragDistance() to get it.
- Some platforms also use minimum velocity for drag operations. You should get it with QStyleHints::startDragVelocity()
- Theres' also a QStyleHints::startDragTime() that denotes the minimum holdtime for a drag operation to start, but it doesn't really fit your case. Again- you're doing something very unusual and weird.
All in all I think you should rethink that double-click design. A drag is typically initiated by a press and move, not double click (press release press release) and move.
-
@Narutoblaze
You can :
-set a bool var to true in mouseDoubleClickEvent
-check it out in mouseMoveEvent
-then set the bool to false in mouseReleaseEvent -
@Chris-Kawa @mpergand Thanks for clearing out for me. I have tried overriding mouseDoubleClickEvent but it does not get called when clicked over tabbar area
void CustomTab::mouseDoubleClickEvent(QMouseEvent *e) { qDebug() << "Double Clicked " << e->pos(); }
working when clicked on empty area not working when mouse is top of tabbar
-
@Narutoblaze That's expected. When you click on an empty area you're clicking on the tab widget. When you click on the bar then you're clicking, well, on the bar, not the tab widget. If you want the click on the bar subclass QTabBar and set it on the tab widget using setTabBar().
-
@Narutoblaze Since I recently burned my feathers, I strongly advise you not to try to go against how the automatisms and things in general have been built, especially if it's just because you're used to doing it in a certain way.
Use the signals available, use installEventFilter, avoid complications just to look cool, simplify the goals.
You'll do the cool stuff in the future, after you get used to it.