需要在 Windows 上将应用程序置于前台
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/204181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Need to bring application to foreground on Windows
提问by Steve Ridout
I've got two applications I'm developing using Qt on windows. I want the user to be able to press a button in one application which makes the other application come to the foreground. (The programs communicate using QLocalSocket and named pipes.)
我有两个正在 Windows 上使用 Qt 开发的应用程序。我希望用户能够按下一个应用程序中的按钮,使另一个应用程序出现在前台。(程序使用 QLocalSocket 和命名管道进行通信。)
Currently I'm using Qt's QWidget::activateWindow() which occasionally brings the application to the foreground, but most of the time it just highlights the program on the taskbar.
目前我正在使用 Qt 的 QWidget::activateWindow(),它偶尔会将应用程序带到前台,但大多数时候它只是突出显示任务栏上的程序。
Can someone please tell me how to do this, preferably using Qt although failing that using the WIN32 API would be fine.
有人可以告诉我如何做到这一点,最好使用 Qt,尽管使用 WIN32 API 失败也没关系。
Unfortunately, I couldn't find a way to do this only with Qt. I solved it using Chris Becke's suggestion of calling SetForegroundWindow from the currently active application.
不幸的是,我找不到仅使用 Qt 的方法。我使用 Chris Becke 的建议从当前活动的应用程序调用 SetForegroundWindow 解决了它。
采纳答案by Chris Becke
Are you sure this is not a debugging issue? The deal is, if an application HAS the foreground, it is allowed to change the foreground.
您确定这不是调试问题吗?交易是,如果应用程序拥有前台,则允许更改前台。
Clicking a button on window A will give that windows thread foreground activation. If it calls SetForegroundWindow (or equivalent) on the other window, that window WILL be given the foreground.
单击窗口 A 上的按钮将使该窗口线程前台激活。如果它在另一个窗口上调用 SetForegroundWindow(或等效的),则该窗口将被赋予前景。
If, on the other hand, it simply sends a message to the other app, which tries to SetForeground on itself, that will fail. AllowSetForegroundWindow is used in situations where a 'legacy' app needs to be given permission - by a foreground app - to take the foreground. Once again, AllowSet... only works if called from a thread that owns the current active foreground window.
另一方面,如果它只是向其他应用程序发送一条消息,该应用程序试图在自身上设置前景,那将会失败。AllowSetForegroundWindow 用于“遗留”应用程序需要获得许可(由前台应用程序)才能进入前台的情况。再一次,AllowSet... 仅在从拥有当前活动前景窗口的线程调用时才有效。
回答by PierreBdR
回答by nurxb01
I have a similar case.
我有一个类似的案例。
I have two Qt applications, A and B, which communicate on a socket. I would like to bring a window of application B up, through a button on application A.
我有两个 Qt 应用程序 A 和 B,它们通过套接字进行通信。我想通过应用程序 A 上的按钮打开应用程序 B 的窗口。
I found that sometimes the widget state is not set correctly, so in the event()
function of my applicatons B's widget I did the following:
我发现有时小部件状态设置不正确,因此在event()
我的应用程序 B 小部件的功能中,我执行了以下操作:
bool MyWidgetB:event ( QEvent * e )
{
QEvent::Type type = e->type ();
// Somehow the correct state of window is not getting set,
// so doing it manually
if( e->type() == QEvent::Hide)
{
this->setWindowState(WindowMinimized);
}
else if( e->type() == QEvent::Show )
{
this->setWindowState((this->windowState() & ~WindowMinimized) |
WindowActive);
}
return QWidget::event(e);
}
I'm sending a command from application A to B. On receiving it, application B calls the following function on itself:
我正在从应用程序 A 向 B 发送一个命令。 收到它后,应用程序 B 调用以下函数:
void BringUpWidget(QWidget* pWidget)
{
pWidget ->showMinimized(); // This is to bring up the window if not minimized
// but beneath some other window
pWidget ->setWindowState(Qt::WindowActive);
pWidget ->showNormal();
}
This works for me, on Windows XP, with Qt 3.3. My MainWidget
is is derived from a QWidget
.
这对我有用,在Windows XP 上,使用 Qt 3.3。My MainWidget
is 是从一个QWidget
.
I have found this is also working with a widget derived from QMainWindow
, but with some issues. Like if some other child windows are open.
我发现这也适用于派生自 的小部件QMainWindow
,但存在一些问题。就像其他一些子窗口打开一样。
For such a case I store the position of the child windows and hide them, then use the BringUpWidget
function to bring my MainWindow
widget, and then restore the child windows.
对于这种情况,我存储子窗口的位置并隐藏它们,然后使用该BringUpWidget
功能带上我的MainWindow
小部件,然后恢复子窗口。
回答by ctd
This is kind of cheesy, but it works for me:
这有点俗气,但对我有用:
this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
this->show();
this->setWindowFlags(Qt::FramelessWindowHint);
this->show();
Or, if you don't have other flags,
或者,如果您没有其他标志,
this->setWindowFlags(Qt::WindowStaysOnTopHint);
this->show();
this->setWindowFlags(0);
this->show();
WindowStaysOnTopHint will almost always force the window to the foreground. Afterwards, you don't really want the window to always stay on top, so reset to whatever the previous flags were.
WindowStaysOnTopHint 几乎总是将窗口强制到前台。之后,您真的不希望窗口始终保持在顶部,因此请重置为之前的标志。
回答by ctd
Use showNormal() to go from an iconified state to a visible state.
使用 showNormal() 从图标化状态变为可见状态。
回答by Ferruccio
I think the APIs you need are AllowSetForegroundWindow()and SetForegroundWindow(). I don't know what the equivalent Qt calls are.
我认为您需要的 API 是AllowSetForegroundWindow()和SetForegroundWindow()。我不知道等效的 Qt 调用是什么。