当不是活动应用程序(窗口)时,如何以编程方式引发 Qt 窗口/小部件?

Posted

技术标签:

【中文标题】当不是活动应用程序(窗口)时,如何以编程方式引发 Qt 窗口/小部件?【英文标题】:How to programmatically raise a Qt Window/Widget when not the active application (windows)? 【发布时间】:2020-02-10 13:32:40 【问题描述】:

我有一个应用程序,它有多个带有 GUI 组件的进程,这些组件需要像一个进程一样进行协调(我们称它为 GUI 系统,并说它使用 TCP 套接字来协调组件)。

为此,如果系统中的一个窗口被激活,则会向系统中的所有其他窗口发送一条消息,以确保它们高于任何不属于我们的 GUI 系统的窗口。

似乎我在纯原生 Qt 中最接近的方法是调用 QWidget.activateWindow()。 如果进程不是活动的 Windows 进程,则其他各种命令(例如 show、raise)似乎不起作用。

让所有其他窗口调用激活窗口的问题在于,它将焦点从我刚刚单击的窗口上移开,使该窗口无法使用(除非我以某种方式在所有其他进程完成激活时调用它激活命令 - 但这会带来很多复杂性和脆弱性)。

【问题讨论】:

【参考方案1】:

在尝试解决我的问题时,我发现很多人都有类似的问题。

当不是活动进程时,似乎没有 Qt Native 方式来调出窗口。

很多人都指向使用 win32 API,但很难找到如何混合 PyQt 和 win32 API 的所有部分,以便在不是活动应用程序时将窗口放在前面,所以这是我最好的尝试:

import win32gui
import win32con

hwnd = self.widget.winId()
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE)

我讨厌它需要两个电话,但它似乎工作。

【讨论】:

我认为 Windows 的意图是除非当前活动的应用程序明确允许窗口进入前台,否则这不起作用,请参阅docs.microsoft.com/en-gb/windows/win32/api/winuser/… @FrankOsterfeld 这肯定与我的问题密切相关。但我实际上并不是想让从属窗口成为“前景”。 --键盘输入定向到窗口,为用户改变各种视觉提示。 -- 我想避免焦点的变化,只是改变窗口的 Z 顺序。

以上是关于当不是活动应用程序(窗口)时,如何以编程方式引发 Qt 窗口/小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式水平平铺某些窗口?

如何以编程方式关闭画中画

Flutter Desktop:如何隐藏窗口(并使进程保持活动状态)?

如何在 Swift 5 中以编程方式在特定屏幕(即主显示器而不是外部显示器)上显示窗口? [苹果系统; Xcode 15]

WinForms:如何确定窗口是不是不再活动(没有子窗口有焦点)?

当 UITabBar 不是 rootViewController 时,如何以编程方式将 UITabBar 与具有 NIB 的不同 ViewController 链接