首发于 C/C++

Qt激活窗口

有一个需求:当处于一定触发条件的时候,把窗口给弹到窗口系统的顶层以提醒用户处理。

原先我的写法直接激活窗口

showNormal();//显示窗口
activateWindow();//激活窗口

这样在windows 7下工作正常,在windows 10下面并不会激活窗口,显示到前面。百度没有搜到解决办法和原因,后来去查了Qt文档后发现activateWindow并不能在windows下起作用。原文为

void QWidget::activateWindow()
Sets the top-level widget containing this widget to be the active window.
An active window is a visible top-level window that has the keyboard input focus.
This function performs the same operation as clicking the mouse on the title bar of a top-level 
window. On X11, the result depends on the Window Manager. 
If you want to ensure that the window is stacked on top as well you should also call raise(). 
Note that the window must be visible, otherwise activateWindow() has no effect.
On Windows, if you are calling this when the application is not currently the active 
one then it will not make it the active window. It will change the color of the taskbar 
entry to indicate that the window has changed in some way. This is because Microsoft does 
not allow an application to interrupt what the user is currently doing in another application.
See also isActiveWindow(), window(), show(), and QWindowsWindowFunctions::setWindowActivationBehavior().

可以发现在MAC下还得加上raise(),在windows下,当别的窗口处于焦点的时候,并不能夺过来焦点。所以像上面这样写的话,只有这个窗口是焦点窗口处于最小化或者隐藏状态的时候,才会弹出,假如在别的窗口工作的时候,并不会激活Qt窗口。看来只能修改为用Win api来实现了

    activateWindow();
    setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
    raise();//必须加,不然X11会不起作用
#ifdef Q_OS_WIN32 //windows必须加这个,不然windows10 会不起作用,具体参看activateWindow 函数的文档
	HWND hForgroundWnd = GetForegroundWindow();
	DWORD dwForeID = ::GetWindowThreadProcessId(hForgroundWnd, NULL);