33

In my Qt-application I open a URL in the default-browser. Afterwards I want to bring the main-window of my application to the front again.

I tried all approaches I could find but none worked. All it does is blink in the taskbar (of Window 7) Here’s an example:

this->viewer->show();
this->viewer->raise();
this->viewer->activateWindow();

*viewer is a pointer to a QmlApplicationViewer which is derived from QDeclarativeView

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Hedge
  • 16,142
  • 42
  • 141
  • 246
  • The docs are quite clear that this is the expected behaviour. Of course you can avoid the issue entirely by integrating any web browsing into your application using QWebKit. – Troubadour May 22 '11 at 12:39
  • Thanks for the hint but I compiled my own libraries without QtWebKit and don't want to use it. – Hedge May 22 '11 at 12:48
  • Why do you want to steal focus from the user's control? – Adrian McCarthy May 22 '11 at 13:36
  • 1
    because it get stolen automatically by the browser which is opened by my application. I just want to bring my window up again after he allowed access for my application on Twitter. – Hedge May 22 '11 at 13:40
  • The exact rules are spelled out in the MSDN Library article for SetForegroundWindow(). – Hans Passant May 22 '11 at 16:12
  • 1
    Thanks to Z order, your application will automatically come back up again once the user closes the browser window. It's the next window in the Z order underneath the newly-opened browser window. You don't have to do anything at all. – Cody Gray - on strike May 22 '11 at 16:14
  • 1
    @Code Gray: Yeah that's correct, but I'd rather put it in front. The browser opens in front as well so where's the difference? – Hedge May 22 '11 at 16:36
  • 2
    So everyone complains but no one wants to give an answer? I have the same problem. When users press on settings a new window opens but if they don't observe it and press again on settings the settings window will stay in back, I want to say "hey, I'm here, here, I popped back in front for you". A solution would be to make setVisibile(false) and then setVisible(true) but I don't like this solution, it should just pop up back in front without closing and opening it again. – Lilian A. Moraru Feb 15 '12 at 12:25
  • Ok, raise() worked for my problem. – Lilian A. Moraru Feb 15 '12 at 12:40
  • I have used QDialog and I have checked as Modal on properties window and it worked. – Burak Hamdi TUFAN Aug 06 '18 at 05:55

7 Answers7

40

try this:

viewer.setWindowState( (windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
viewer.raise();  // for MacOS
viewer.activateWindow(); // for Windows

it work in my project ( in my project viewer is QMainWindow): https://github.com/iptton/Rythem .

iptton
  • 593
  • 1
  • 4
  • 11
  • 1
    "The enum value `Qt::WindowActive` is not an accepted parameter". From the QWindow::setWindowState docs. – ManuelSchneid3r Jan 07 '16 at 19:45
  • https://fossies.org/diffs/qt-everywhere-opensource-src/5.6.1_vs_5.7.0/qtbase/src/gui/kernel/qwindow.cpp-diff.html as the source code mentioned: when the parameter equals to Qt:WindowActive , setWindowState will return directly. And the raise() activityWindow() works for this situation. But if the state of window isn't Minimized ,the state is not equals to Qt::WindowActivie . And that's why the code works. – iptton Feb 15 '17 at 03:52
  • 1
    This worked for me on Win10. All I needed was the setWindowState (combined with show() to restore app from tray) thanks! – smoothware Sep 16 '17 at 23:00
  • @RuiBotelho If you minimize your window , then your method cannot bring your window to front . – iMath May 06 '19 at 01:34
11

This problem is specific to Windows. If the active window belongs to some process, then Windows does not allow other processes to change the active Window.

(Do not try the following: https://wiki.qt.io/Qt_project_org_faq#QWidget_::activateWindow.28.29_-_behavior_under_windows)

Hossein
  • 4,097
  • 2
  • 24
  • 46
Johan Råde
  • 20,480
  • 21
  • 73
  • 110
  • 1
    Thanks for the explanation. Your approach is pretty hacky. As I'm a die-hard portable software advocate I don't want to fiddle with the registry of someone's PC. Is there another approach like setting the window topmost? – Hedge May 22 '11 at 12:41
  • 17
    This isn't a Windows-specific _problem_. It's a _solution_ to all the crappy, focus-stealing applications. Windows signals that the application wants the user's attention, but it leaves the user in charge. – Adrian McCarthy May 22 '11 at 13:33
  • 7
    Doesn't matter what color hat you wear: that only "fixes" it on your local machine, not the client's. Thanks to UAC, also introduced in later versions of Windows, my registry settings are safely off-limits to your rogue application! – Cody Gray - on strike May 22 '11 at 16:13
  • 1
    activateWindow() works nicely for me under win'7 with 4.8.6 :) – mlvljr May 21 '14 at 11:58
  • I get the same problem on MacOS – c z Jun 01 '17 at 09:07
  • Great answer, unfortunately it is not good news :)) – Alex Seceleanu Aug 31 '21 at 12:31
9

I did it like this:

{
 this->show(); // Restore from systray
 this->setWindowState(Qt::WindowState::WindowActive); // Bring window to foreground
}

assuming "this" is your QMainWindow. Worked like a charm.

Vandrey
  • 531
  • 1
  • 8
  • 23
3
for ( QWindow* appWindow : qApplication.allWindows() )
{
  appWindow->show(); //bring window to top on OSX
  appWindow->raise(); //bring window from minimized state on OSX

  appWindow->requestActivate(); //bring window to front/unminimize on windows
}

Note that this also brings up the window from other virtual desktops on both OSX and Windows. I did not test this on linux, it may work though.

agnu17
  • 398
  • 2
  • 9
2

This issue is not specific to Windows....I have the same issue on Linux. My solution was to close() the window before I re open() it.

Bruce Chidester
  • 621
  • 1
  • 5
  • 16
0

For Windows I did it with WinAPI. Also you need to know the window title;

#include <windows.h>
const QString windowTitle = "Some title";

HWND hwnd = ::FindWindowA(NULL, windowTitle.toLocal8Bit());
if (hwnd != NULL) {
    if (::IsWindowVisible(hwnd)) {
        ::SwitchToThisWindow(hwnd, TRUE);
    }
}
 
Alex Nevskiy
  • 347
  • 1
  • 2
  • 10
  • Funny behavior - trying to bring the app in front - it stays stubbornly behind but the icon on taskbar blinks for attention – Thalia Sep 20 '21 at 15:58
0

The following is borrowed from the forum and it works for me:

auto eFlags = viewer.windowFlags();
viewer.setWindowFlags(eFlags|Qt::WindowStaysOnTopHint);
viewer.show();
viewer.setWindowFlags(eFlags);
viewer.show();
sercxjo
  • 328
  • 2
  • 12