Window steals focus
Ben van Gompel
We have an application consisting of two windows. During runtime we add and remove widgets from those windows, initiated by actions on one of the windows (say Window1). What happens is that focus changes from Window1 to Window2 as a consequence of the widgets changing on Window2, and as far as I can see there is no code that explicitly does that.
So, my question is: what can make a window obtain focus? Are there are specific Qt calls that may lead to a window gaining focus?
I understand this may be a bit vague, especially since it is lacking code snippets, but initially I want to get a general understanding of focus policy in Qt.
Hi and welcome to devnet,
Generally when you show a new widget, it gets the focus. one thing you can try is to call setFocus on your Window1 widget.
You also have more information on focus handling here
Hope it helps
hard to tell what happens without seeing the code.
The issue mentioned by SGaist should only kick in when you call show() on your widgets before setting the parent. So they result in a separate window for a short period of time. Activating windows get the input focus.
You can prevent this by calling setAttribute(Qt::WA_ShowWithoutActivating) on the widget before showing.
But to make sure set a breakpoint in the focus-in/out event handler and check in the method call stack what caused the focus change.
Turns out the focus change is indeed being caused by a ActivatedWindow event. So, now I have to figure out where that came from :-)
As far as I know we don't directly call show on the new widget, but there is this 3rd party code, which may just do that.
So, it took me some time to figure out what happened. Holiday break didn't help either :-) Happy new year all!
It turns out, the problem is caused by our use of QTabWidget, which internally uses QStackedWidget. We can call setAttribute(Qt::WA_ShowWithoutActivating) on the QTabWidget but that does not seem to affect the internal QStackedWidget.
Besides writing our own QTabWidget version I don't see a way around this.
One thing you can try is to use findChild on your QTabWidget to get the internal QStackedWidget and apply the attribute on it.
Further debugging shows my problem is not with 'show' but with 'setParent'. Somehow, that results in the window being activated. Seems to happen in external (for me) code.
Qt5Guid.dll!QWindowSystemInterfacePrivate::ActivatedWindowEvent::ActivatedWindowEvent(QWindow * activatedWindow, Qt::FocusReason r) Line 144 C++ Qt5Guid.dll!QWindowSystemInterface::handleWindowActivated(QWindow * tlw, Qt::FocusReason r) Line 110 C++ qwindowsd.dll!QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow * platformWindow) Line 1178 C++ qwindowsd.dll!QWindowsContext::windowsProc(HWND__ * hwnd, unsigned int message, QtWindows::WindowsEventType et, unsigned __int64 wParam, __int64 lParam, __int64 * result) Line 1037 C++ qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1236 C++ [External Code] qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1245 C++ [External Code] qwindowsd.dll!QWindowsWindow::setParent_sys(const QPlatformWindow * parent) Line 1252 C++ qwindowsd.dll!QWindowsWindow::setParent(const QPlatformWindow * newParent) Line 1226 C++ Qt5Guid.dll!QWindow::setParent(QWindow * parent) Line 596 C++ Qt5Widgetsd.dll!QWidgetPrivate::setParent_sys(QWidget * newparent, QFlags<enum Qt::WindowType> f) Line 10521 C++ Qt5Widgetsd.dll!QWidget::setParent(QWidget * parent, QFlags<enum Qt::WindowType> f) Line 10376 C++ Qt5Widgetsd.dll!QWidget::setParent(QWidget * parent) Line 10311 C++ Qt5Widgetsd.dll!QLayout::addChildWidget(QWidget * w) Line 929 C++ Qt5Widgetsd.dll!QStackedLayout::insertWidget(int index, QWidget * widget) Line 223 C++ Qt5Widgetsd.dll!QStackedWidget::insertWidget(int index, QWidget * widget) Line 178 C++ Qt5Widgetsd.dll!QTabWidget::insertTab(int index, QWidget * w, const QIcon & icon, const QString & label) Line 457 C++ Qt5Widgetsd.dll!QTabWidget::addTab(QWidget * child, const QIcon & icon, const QString & label) Line 400 C++