How to detect that my application lost focus in Qt? - c++

I'm displaying a popup window when the mouse cursor is over a certain widget and I'd like to hide this popup when the mouse leaves the widget.
To do it, I reimplemented leaveEvent(). This seems to work in all cases except when switching to another application by Alt+Tab. I figured out that I probably need to catch another event, but somehow I can't find the proper one. Can you suggest one?

The event you are looking for is QEvent::ApplicationDeactivate: "The application has been suspended, and is unavailable to the user".
You can install an event filter on your QApplication instance to catch this event. See the documentation for QObject::installEventFilter(QObject*) for more details how this works.
Since Qt 5.2 the QEvent::ApplicationDeactivate event is deprecated. The correct way to identify when an application is deactivated in Qt 5.2 (or later) is to use the QGuiApplication::applicationStateChanged(Qt::ApplicationState state) signal.

Related

Does Qt provide a way to get notified when the user starts and/or stops moving or resizing a top-level window?

While answering a different StackOverflow question I realized that a 100% correct solution would need to know when the Qt application's window was being dragged or resized by the user's mouse, so that it would refrain from moving or resizing itself during that period, and thereby avoid "fighting with the user" for control of the window.
However, I don't know of any mechanism for a Qt app to be notified when the user pressed down the left-mouse button on the window's title bar, or when the user releases the left-mouse button afterwards... I assume that is because that functionality is handled by the OS's window-manager rather than by the Qt library. That said, is there any secret way to do it? Cross-platform would be best, but OS-specific solution are also of interest.

Qt application does not respond to mouse and keyboard events

I recently upgraded my application from using a dynamic build of QT to a static. However, ever since the upgrade I am not able to:
Trigger mouse events: I am not able to click any widget, there is simply no animation (window is static).
Trigger keyboard events: I can not enter a value in the default focused QSpinBox.
Some remarks:
When the upgrade was performed, no style was set for the application (however in the dynamic build, there was a style). I fixed this by using application.setStyle("fusion")
I see the cursor of the QSpinBox blinking. In my experience this indicates that the GUI-thread is not "stuck" somewhere.
I found the problem: the GUI thread was not the main thread (this is also being logged)

Which event belongs to window focus changing in qt c++?

I want to save the focused window's title, i made this part but i dont know is there any QEvent which catches all (non-application) focusChanged event? Like switching from Chrome to Qt Creator. I made an alternative solution that checks in every second if the topmost window title has changed but this is so rude. I need cross-platform solution if possible.
EDIT
I am using QT 5.9.0
Quick answer:
Qt only has focus events for it's own windows and widgets. See http://doc.qt.io/qt-5/qfocusevent.html#details for start point.
There is no event for focus in other applications.
Details:
For multi-platform solution is needed to have more general point of view. On some (X window) systems where keyboard focus is in window under mouse. But that window becomes topmost only after click. On Mobile platforms there is only one active application. And application is not allowed seeing when other applications are activated. So in my understanding there is no full multi-platform solution.
Windows only extensions are in the Qt Windows Extras. http://doc.qt.io/qt-5/qtwinextras-overview.html. But there is nothing focus change related unfortunately.

How can I detect a global drag event ?

I have a window to drop a file in. What I would like to do is being able to change the appareance of the window when the user start to drag something on his desktop for example (So not on the window).
For that I need to catch a global event from window. This event is called GiveFeedBack I think (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.givefeedback(v=vs.110).aspx) ? But how can I detect it on Qt ?
Thanks
You could set a windows hook for mouse events and look out for potential drag/drops or alternatively add hooks onto message procs of windows from other running processes (not particularly nice).
UAC may stop this working in some cases.
See:
SetWindowsHookEx
There may also be some COM interfaces for this. But you may not get events when the drag starts. See RegisterDragDrop.

Best approach to retrieve values from a QML Modal dialog

In my QT C++ application i call a QML ModalDialog with 2 buttons (OK/CANCEL), which displays correctly on screen and so, no problem there.
However i'm struggling to find a way to retrieve in my QT C++ application which button was pressed.
I'm unable to somehow "freeze" when i call the QML ModalDialog, to wait there until the user press OK Button or Cancel Button
What i see is that application calls the QML ModalDialog, and immediately exit that part and continue.
QMetaObject::invokeMethod can call a QML function and have a return value, but it just doesn't wait for the user press one of the buttons, it just exits immediately, so no use.
I want to use this QML ModalDialog in several places of my application (the QML modal
dialog can have different text passed from my QT C++ application), so i was looking to a generic solution for this.
Basically and generic speaking i'm looking for something like this:
C/C++
return_value = QML_Modal_Dialog(....)
Can someone point me in the right direction? Thanks
QML modal dialog comes with two signals 'accepted' and 'cancelled'. If you provide handlers for these two signals in your code, you would be able to know which button got pressed.
You can refer to the below for reference.
Modal Dialog Ref 1
Modal Dialog Ref 2
Hope this helps!
Despite that the question is too old maybe my answer will help someone else.
I faced the same problem with Dialogs in QML. You think about it in imperative way, while QML is a declarative language that doesn't allow you to stop the flow of program and wait for the user's choice.
As Purnima suggested you should use signal handlers (you can find the list of them for Qt 5.6 here). Move some of your app's logic to the signal
handlers.
For example - if your function a() is executed based on the user's choice in dialog you should instead call it inside the dialog in its signal handlers (e.g. onAccepted or onRejected) with two different parameters based on the type of signal handler. Think about it as splitting the flow in two streams.