如何让Python窗口始终处于最上层?

10 投票
3 回答
14049 浏览
提问于 2025-04-15 14:37

我在用Python写一个小程序,这个程序会打开一个小窗口,需要让这个窗口始终在其他窗口的上面。我觉得这个功能和操作系统有关,在GNU-Linux的GNOME环境下应该怎么做呢?

[更新 - Windows的解决方案]

太好了,我想我搞定了。我在Vista 64位系统上使用Python 2.5.4和Pygame 1.9.1,使用的是Eclipse。所以这个解决方案是针对Windows系统的。SetWindowPos这个函数的详细信息可以在这里找到。我会在我的解释中提到这个。

导入的库:

from ctypes import windll

然后我设置了一个变量,用来调用user32里的"SetWindowPos":

SetWindowPos = windll.user32.SetWindowPos

现在,假设我刚刚创建了一个窗口:

screen = pygame.display.set_mode((100,100), pygame.NOFRAME)

接下来的这一行是关键。这一行代码让窗口始终在其他窗口的上面。

SetWindowPos(pygame.display.get_wm_info()['window'], -1, x, y, 0, 0, 0x0001)

基本上,你需要提供hWnd(窗口句柄),这个句柄是通过调用display.get_wm_info()得到的窗口ID。这样,函数就可以修改你刚刚初始化的窗口了。

-1就是我们的hWndInsertAfter

MSDN网站上说:

要将一个窗口设置为最上层窗口,可以将hWndInsertAfter参数设置为HWND_TOPMOST,并确保没有设置SWP_NOZORDER标志,或者通过在Z顺序中设置窗口的位置,使其位于任何现有的最上层窗口之上。当一个非最上层窗口被设置为最上层时,它所拥有的窗口也会被设置为最上层。但它的拥有者不会改变。

所以,-1确保这个窗口在任何其他现有的最上层窗口之上,但这可能并不总是有效。也许-2会比-1更有效?目前对我来说是有效的。:)

xy指定了窗口的新坐标。我希望窗口在调用SetWindowPos函数时保持在当前的位置。可惜我找不到简单的方法把当前窗口的(x,y)位置传递给这个函数。我找到了一种变通方法,但我觉得不应该在这个问题中引入新话题。

0, 0,本来是用来指定窗口的新宽度和高度(以像素为单位)。不过,这个功能已经在你的pygame.display.set_mode()函数中实现了,所以我把它们留在了0。0x0001会忽略这些参数。

0x0001对应于SWP_NOSIZE,是我唯一的uFlag。所有可用的uFlags的列表可以在提供的文档页面上找到。它们的一些十六进制表示如下:

  • SWP_NOSIZE = 0x0001
  • SWP_NOMOVE = 0x0002
  • SWP_NOZORDER = 0x0004
  • SWP_NOREDRAW = 0x0008
  • SWP_NOACTIVATE = 0x0010
  • SWP_FRAMECHANGED = 0x0020
  • SWP_SHOWWINDOW = 0x0040
  • SWP_HIDEWINDOW = 0x0080
  • SWP_NOCOPYBITS = 0x0100
  • SWP_NOOWNERZORDER = 0x0200
  • SWP_NOSENDCHANGING = 0x0400

就这些了!希望对你有用!

感谢John Popplewell的帮助,邮箱是john@johnnypops.demon.co.uk。

3 个回答

0

我在尝试解决一个类似的问题时,发现了这个使用Pmw模块的解决方案。

http://www.java2s.com/Code/Python/GUI-Pmw/Showglobalmodaldialog.htm

0

我其实对Python了解不多,但我在网上搜索“pygtk总在最上面”时找到了这个:

http://www.mail-archive.com/pygtk@daa.com.au/msg01370.html

那里的解决方案是:

transient.set_transient_for(main_window)

你也可以试着搜索“x11总在最上面”之类的东西。这个背后的概念是,你在给窗口管理器一个“提示”,让它知道这个窗口应该保持在其他窗口的上面。不过,窗口管理器有自己的决定权,可以随意处理。

我还看到过在使用像Fluxbox这样的窗口管理器时,有层的概念,所以也许可以通过改变窗口出现的层级来解决这个问题。

8

这个问题更像是你在使用哪个窗口工具包?我通过查找PyGTK等相关信息找到了这个链接


gtk.Window.set_keep_above

正如之前提到的,是否遵循这个设置取决于窗口管理器。

编辑:添加SDL相关内容 Pygame使用SDL来处理显示工作,显然和窗口工具包不太兼容。关于如何让SDL窗口始终在最上面,可以在这里找到讨论。

撰写回答