In Qt development, it is common to see code like this:
| |
Many people use this sequence, but not everyone can clearly explain what each call actually does or why this order is commonly recommended.
At first glance, all three may seem related to “bringing a window to the front.” But if you read the Qt source code, they operate at three different levels:
show(): makes the widget visibleraise(): adjusts the Z-order so the widget is stacked higheractivateWindow(): requests that the window become the active window and receive keyboard focus
These are not the same thing, so the order is not arbitrary.
1. show(): make the window visible first
Let’s start with QWidget::show():
| |
There are two key takeaways here.
1.1 show() is essentially setVisible(true)
For a normal child widget, show() simply calls setVisible(true).
For a top-level window, Qt first checks the platform integration and window flags to decide whether it should be shown as:
- fullscreen via
showFullScreen() - maximized via
showMaximized() - normally visible via
setVisible(true)
So the main job of show() is simply this: make the widget visible.
It does not:
- bring the window to the top of the stack
- force activation or focus
- restore a minimized window to the normal state
1.2 show() does not clear minimized or maximized state
This source comment is especially important:
| |
That means show() does not call showNormal() automatically, because Qt does not want to overwrite an existing minimized or maximized state.
So if a window is already minimized, calling show() again does not necessarily mean “restore the window.” That is exactly why showNormal() is the better choice in many restore scenarios.
2. showNormal(): restore from minimized, maximized, or fullscreen
Now look at QWidget::showNormal():
| |
It does two things:
- Clears these state bits:
Qt::WindowMinimizedQt::WindowMaximizedQt::WindowFullScreen
- Calls
setVisible(true)
So the meaning of showNormal() is very explicit: restore the window to the normal state and show it.
That makes it a better fit than show() in situations like these:
- the main window has been minimized to the taskbar
- a single-instance app is launched again and needs to restore the existing window
- clicking a tray icon should bring a hidden or minimized window back to the desktop
In short:
show()answers “is it visible?”showNormal()answers “is it restored to the normal state?”
3. raise(): adjust stacking order, not window activation
Here is QWidget::raise():
| |
This function is easier to understand if you separate child widgets from top-level windows.
3.1 For child widgets, raise() mostly reorders the parent’s children list
This line is the key:
| |
For a non-window widget, raise() moves the widget to the end of the parent’s children list, which changes the painting and stacking order among sibling widgets.
After that, Qt may also:
- call
create()if needed - recompute the affected region
- call
invalidateBackingStore(region)to trigger repainting
So for child widgets, the core meaning of raise() is: place this widget above its sibling widgets.
3.2 For top-level windows, the important part is d->raise_sys()
For windows, this line matters most:
| |
This tells us two things:
raise()eventually delegates to the platform layer- it only does so if the native window has already been created
That leads to an easy-to-miss detail:
If a top-level window has not been created yet, calling
raise()alone may do nothing.
A top-level window usually becomes fully created after show() or setVisible(true). So from the source-code perspective, calling show() before raise() is the sensible order.
3.3 raise() does not mean “give me focus”
raise() changes stacking order. It does not activate the window.
Even if a window is brought visually higher, that does not mean it has become the active window or received keyboard focus.
So this:
| |
only means “please bring this window higher in the stack,” not “the user can type into it immediately.”
4. activateWindow(): request activation of the top-level window
Now look at QWidget::activateWindow():
| |
The implementation is short, but it reveals a lot.
4.1 It operates on the top-level window, not the current child widget itself
The code uses:
| |
So even if you call activateWindow() on a child widget, Qt ultimately tries to activate the top-level window that contains it.
That means activateWindow() does not mean “give this exact widget focus.” It means:
Make the top-level window containing this widget become the active window.
4.2 It calls requestActivate(), not a force-activate API
The key line is:
| |
The word is request, not force.
Qt can ask the window system to activate the window, but whether that request succeeds depends on platform policy.
Qt’s own documentation is very explicit about this:
- on X11, the result depends on the window manager
- if you also want the window stacked on top, call
raise()as well - the window must be visible, otherwise
activateWindow()has no effect - on Windows, if your app is not currently the active application, the OS usually will not allow it to steal the foreground window; it may only highlight the taskbar entry instead
That is why activateWindow() sometimes seems to work and sometimes does not.
Qt is doing its part, but it cannot bypass the operating system’s foreground-window policy.
5. Why the recommended order is showNormal() / show() → raise() → activateWindow()
The source code makes the recommended order fairly direct.
5.1 First, make the window visible
The documentation for activateWindow() says:
the window must be visible, otherwise activateWindow() has no effect.
And internally it also depends on:
| |
If the window has not been shown yet, the window handle may not be ready, and the call can effectively become a no-op.
So the first step should be show() or showNormal().
5.2 Then adjust the stacking order
raise() is responsible for bringing the window higher in the Z-order.
Qt’s documentation for activateWindow() even says:
If you want to ensure that the window is stacked on top as well you should also call raise().
In other words, activation and stacking order are separate concerns.
If you call only activateWindow(), some platforms may not place the window as prominently as you expect. raise() fills that gap.
5.3 Finally, request activation
Once the window is:
- visible
- already brought as high as possible in the stack
calling activateWindow() makes the intent complete.
So the common recommended sequence is:
| |
If the window may be minimized, an even better choice is:
| |
6. Summary
From the Qt source code, the responsibilities of these APIs are clearly separated:
show(): make the window visible, but do not restore normal state or request focusshowNormal(): clear minimized, maximized, and fullscreen state, then show the windowraise(): adjust Z-order so the window is stacked higheractivateWindow(): ask the window system to activate the top-level window
So in practice:
- if you want to restore a minimized window, use
showNormal() - if you want to bring the window visually forward, use
raise() - if you want to request focus, use
activateWindow() - if you want the full “show it and try to bring it to the front” behavior, use
showNormal()/show()+raise()+activateWindow()
The most commonly useful sequence, and the one that best matches the source-code semantics, is:
| |
If the window is not minimized, you can replace showNormal() with show().
