Mouseup programmatically in Qt? - qt

Background
I'm building an application which runs in the background, and where the mouse cursor is moved programmatically into a dialog when the dialog "pops up". I have done this using QCursor.setPos
Problem
The problem I'm having is that if the mouse button is pressed down when the user is interacting with something outside the application this might lead to unwanted things happening. For example if the user is changing the volume and the mouse is moved the volume might go to max or min
Question
Is there any way (in Qt) to do a mouseup programmatically?
If I do this before changing the position of the cursor it seems to me that there is less risk of problems (though there might be other problems resulting from this approach)

Related

How to hide mouse cursor in Qt Application?

qApp->setOverrideCursor() method works successfully, if I want to hide mouse cursor, except one condition. If I add a dialog that is modal, and while it is shown, if the cursor is out of dialog's borders, it is shown again. Have you got any idea about the problem?
It does not matter how the solution for hiding mouse cursor is; whether by Qt or at the operating system level. My operating system is Windows 7.
You cannot hide the mouse cursor when it leaves your window (or dialog-window), because it is then handled by the window-manager of your OS. A workaround would be to constrain the mouse to your window/dialog, so it cannot leave. You will either need to look through the MSDN to find the specific windows functions to do it, or do it like in kshegunov's code example on the Qt-forums: https://forum.qt.io/topic/61832/restrict-mouse-cursor-movement/12

Custom Touch behavior in Windows 7 with Qt/QML application

I am developing a touch application for Windows 7 with Qt/QML. The end-user-device has Windows 7's native touch behavior, i.e.: When touching the screen, a point appears on the last-touched-point, and when ending the physical touch, Windows puts that point on the now-touched point and runs in the on-clicked-Event.
Compared to the behavior one knows from standard Windows mouse-usage, this leads to a different behavior as soon as it comes to e.g. clicking some button: A mouse user will expect that the button changes color to the pressed-down-color when mouse button goes down, while the color changes to the default color again when the mouse button goes up.
In my application, I want to have a customized way of touch feedback: What is currently being touched should be marked using changed colors of buttons, imitating a "mouse goes down" when the actual physical touch begins and imitating a "mouse goes up" when the actual physical touch ends.
My application will run fullscreen, so an actual possibility would be to change the system's behavior on application start and change it back to default on applications end.
Such a behavior would effectively be the same as the standard behavior on e.g. all Android devices I know.
I searched through all the MouseArea and MultiPointTouchArea elements, trying to find a way to just make the click-reaction behavior different to the standard behavior. However I did not even find a way to capture the begin of the actual touch ... All the things which I want to happen at the begin of the touch actually happen when the touching ends.
Edit:
It does not matter if I use a QML button or a mousearea plus the MouseArea.pressed property: Nothing will be "pressed" before the finger leaves the touch and the onClicked() even is called.
Possibly related:
Adobe AIR: touch screen doesn't trigger mouse down event correctly - but I did not find a way to access the functions like Multitouch.inputMode (which are mentioned in the first reply) from a native Qt application.
How can I achieve the described behavior for my application?
The solution for this issue is to disable "Press and Hold" for the application. This is what can be done in a system-wide setting using ...
Control Panel -> Pen and Touch -> Touch -> Press and Hold -> Settings -> uncheck 'Enable press and hold for right-clicking'
The only solution I found to to this in native code can be found here:
http://msdn.microsoft.com/en-us/library/ms812373.aspx
I checked that this is at least still working for Windows 7. To get it working for QML, I searched for the QWindow* in QQmlApplicationEngine::rootObjects() and used its winId as a HWND. With that HWND, I called the TogglePressAndHold function from the link before app.exec().

hide system cursor in system wide

I want to hide system cursor for 10s for some reason ,but I found
cursor.setShape(Qt.BlankCursor)
can only hide mouse cursor that is associated with QWidgets ,not in system wide ,i.e. when mouse cursor is hovering on QWidgets, it is invisible ,otherwise it is visible ,so is there any way to hide system cursor in system wide?
The win32 system call ShowCursor works per-window only. You can access this from either ctypes or pywin32's win32api. But apparently the cursor drawing is controlled by display driver and can only be affected by specific windows. You can't force another window to hide its cursor. Two options:
use ShowCursor(False) on your window, and for the display background, create a root window application that you spawn from your GUI app, it hides cursor; your app would cause it to exit after 10 seconds, but again if user moves mouse over other app windows they will see cursor.
make your application a root window application; then while in view, ShowCursor(False) will make cursor disappear everywhere on screen except system toolbar (which is a good thing).
I don't think it is a good idea anyways; what if your app crashes while the mouse is hidden? Then user can't use their desktop easily. Definitely good reason that this is not allowed.
Best approach is to think of a different solution to whatever problem led you to try cursor hiding.

Getting a mouse drop event in Qt 5 if mouse doesn't move before mouse release

Something seems to have changed in Qt 5: you can't get a drop or move event if you don't move at least one pixel from the start point where you were when QDrag::exec() was called. Try putting a breakpoint in the dropEvent of the Draggable Icons Sample, then click a boat and release it without moving the mouse. That generates an "ignore" without any drop signal.
(This is on Kubuntu 13.10 with Qt 5.1.)
When teaching how to start a drag operation, the documentation suggests you might use manhattanDistance() to determine if the mouse has moved enough to really qualify as "the user intending to start a drag". But you don't have to use that; you can start up a QDrag on the click itself.
Anyone know of a workaround to have that same kind of choice on the drop side, or is that choice gone completely? :-/
Why I care: I've long had frustrations trying to get a tight control on mouse behavior in GUI apps—Qt included. There seems to be no trustworthy state transition diagram you can draw of the invariants. It's a house of cards you can disprove very easily with simple tests like:
virtual void enterEvent(QEvent * event) {
Q_ASSERT(!_entered);
_entered = true;
}
virtual void leaveEvent(QEvent * event) {
Q_ASSERT(_entered);
_entered = false;
}
This breaks all kinds of ways, and how it breaks depends on the platform. (For the moment I'll talk about Kubuntu 13.10 with Qt 5.1.) If you press the mouse button and drag out of the widget, you'll receive a leaveEvent when you cross the boundary...and then another leaveEvent when the button is released. If you leave the window and activate another app in a window on screen and then click inside the widget to reactivate the Qt app, you'll get two consecutive enterEvents.
Repeat this pattern for every mouse event, and try and get a solid hold on the invariants...good luck! Nailing these down into a bulletproof app that "knows" it's state and doesn't fall apart (especially in the face of wild clicking and alt-Tabbing) is a bit of a lost cause.
This isn't good if your program does allocations and has heavy processing, and doesn't want to do a lot of sweeping under the rug (e.g. "Oh, I was doing some processing in response to being entered... but I just got entered again without a leave. Hm, I guess that happens! Throw the current calculations away and start again...")
In the past what I've done is to handle all my mouse operations (even simple clicking) with drag & drop. Getting the OS drag & drop facility involved in the operation tended to produce a more robust experience. I can only presume this is because the testers actually had to consider things like task switching with alt-Tab, etc. and not cause multiple drop operations or just forget that an operation had been started.
But the "baked in at a level deeper than the framework" aspect actually makes this one-pixel-move requirement impossible to change. I tried to hack around it by setting a timer event, then faking a QMouseEvent to bump the cursor to a new position once the drag was in effect. However, I surmise that the drag and drop is hooked in at the platform level, and doesn't consult the ordinary Qt event queue: src/plugins/platforms/xcb/qxcbdrag.cpp
The issue has--as of 1-May-2014--been acknowledged as a bug by the Qt team:
https://bugreports.qt-project.org/browse/QTBUG-34331
It seems that me bountying it here finally brought it to their attention, though it did not generate any SO answers I could accept to finalize the issue. So I'm writing and accepting my own. Good work, me. (?) Sorry for not having a better answer. :-/
There is another unfortunate side effect of the Qt5 change, pointed out by a "Dmitry Mordvinov":
Same problem here. Additionally app events are not handled till the first mouse event after drag started and this is really nasty bug. For example all app animations are suspended during that moment or application hangs up when you try to drag with touch monitor.
#dvvrd had to work around it, but felt the workaround was too ugly to share. So it seems that if you're affected by the problem, the right thing to do is go weigh in...and add your voice to the issue tracker to perhaps raise the priority of a solution.
(Or even better: patch it and submit the patch. 'tis open source, after all...)

Mouse button status

From what I see, QApplication::mouseButtons() may return no buttons even when a button is held down. This happens when you have clicked a side of a window for re-sizing. It's coherent with the docs because mouseButtons() reflects the state from the flow of QEvent::mouseButtonPress, etc. However, I need just to know if the button is held down. Does any one know if it's possible through the Qt API?
I think it's not possible. Mouse events outside an application's window are not passed to its event handlers. Dragging mouse borders is one of such events, it's processed by the window system. Another example is clicking on other windows. Usually an application doesn't know what the user does with other windows. You need to install system-wide event listener or use native API features(e.g. GetAsyncKeyState on Windows) to determine that. This behavior is unusual and possibly dangerous. In most cases it's not useful, and it seems that Qt doesn't have this ability.

Resources