如何让PyQT4窗口跳到最前面?

23

我希望实现一个 PyQT4 窗口(QtGui.QMainWindow),当应用程序从另一台机器接收到指定消息时,窗口能够跳到前面。通常情况下,该窗口处于最小化状态。

我尝试过使用 raise_()show() 方法,但都没有效果。


在 PyQt5 中,对于从 QtWidgets.QMainWindow 派生的类,show() 和顺序 raise_() 对我来说工作得很好。 - Konstantin Burlachenko
6个回答

23

这个是有效的:

# this will remove minimized status 
# and restore window with keeping maximized/normal state
window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)

# this will activate the window
window.activateWindow()

在Win7上,对我来说两者都是必需的。

setWindowState用于恢复最小化的窗口并将其置于焦点位置。但如果窗口只是失去了焦点而没有最小化,则它不会将窗口置于焦点位置。

activateWindow 将窗口置于焦点位置,但不会将窗口恢复到最小化状态。

使用两种方法可以达到期望的效果。


14
这对我来说可以提高窗口的高度,但不总是让它保持在最上面:
# bring window to top and act like a "normal" window!
window.setWindowFlags(window.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)  # set always on top flag, makes window disappear
window.show() # makes window reappear, but it's ALWAYS on top
window.setWindowFlags(window.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint) # clear always on top flag, makes window disappear
window.show() # makes window reappear, acts like normal window now (on top now but can be underneath if you raise another window)

3
我尝试了此页面上的所有其他建议,而这是在Windows 10上为我工作的唯一方法:window.setWindowFlags(window.windowFlags() | QtCore.Qt.WindowStaysOnTopHint); window.show() - Waxrat
实际上,在Windows 10上,两者都对我不起作用。也许是一些奇怪的Nvidia问题。 - wordsforthewise
这个技巧在最新的Win 10上也可以很好地工作。赞! - Mecanik
在我尝试使用Windows 11时,这是唯一有效的解决方案。然而,有时我会看到窗口打开然后关闭再打开;看起来很不好看。 - Koray

5

我尝试了上述方法都没有成功,最终不得不直接使用win32 api,在C版本中使用一个hack here。这对我有用:

from win32gui import SetWindowPos
import win32con

SetWindowPos(window.winId(),
             win32con.HWND_TOPMOST, # = always on top. only reliable way to bring it to the front on windows
             0, 0, 0, 0,
             win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
SetWindowPos(window.winId(),
             win32con.HWND_NOTOPMOST, # disable the always on top, but leave window at its top position
             0, 0, 0, 0,
             win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
window.raise_()
window.show()
window.activateWindow()

1
补充一下Zuzu Corneliu的答案。我也尝试了所有方法但都失败了,但对我有效的方法是将窗口最小化,然后再将其从最小化状态还原。虽然zuzu使用的方法出现了某些问题并没有为我解决问题,所以我不得不采用其他方法。
我将这种方法添加到了我的QDialog / QMainWindow中:
def reShow(self):
    self.showMinimized()
    self.setWindowState(self.windowState() and (not QtCore.Qt.WindowMinimized or QtCore.Qt.WindowActive))

这对我来说就够了!而且不需要最小化显示。 - ullix

1
对于我在Windows 10上使用NVidia GPU,这个方法有效:
from PyQt4 import QtCore
# create window here...
window.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

我在这个答案中找到了它:https://dev59.com/dmct5IYBdhLWcg3wLqnx#12280956


0

对于那些因此问题感到恼火并且没有成功使用提供的任何方法来解决它(例如,如果我在启动Python脚本但Qt窗口出现之前立即单击另一个窗口,则PyQt5对我无效),这里是最终为我工作的技巧:

wnd.showMinimized() # this is the trick: minimize first
wnd.show() # or wnd.showMaximized() if you want it shown maximized

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接