28

我正在将 Python 2 与Tkinterand一起使用PyObjC,然后我正在使用py2app.

该程序运行良好,但每当我打开程序时,窗口都会以隐藏状态启动,因此在我单击 Dock 上的图标将其调出之前,它不会出现。

有没有办法控制这一点,使窗口位于应用程序启动时打开的其他窗口之上?

澄清一下,它不必在应用程序运行的整个过程中都位于顶部。我只需要它在启动时位于其他窗口的顶部。

4

8 回答 8

48

我知道这是一个老问题,但我发现没有人想出我所拥有的简单解决方案很奇怪,

app = SampleApp()

app.attributes('-topmost', True)
app.update()
app.attributes('-topmost', False)

app.mainloop()
于 2017-07-12T18:15:30.780 回答
27

我今天遇到了同样的问题。OSX 狮子 10.7.2。mainloop()在解决问题之前添加此代码。

root.call('wm', 'attributes', '.', '-topmost', '1')

但在您关闭它之前,该窗口始终位于其他窗口之上。为了真正解决问题,我们需要使用 py2app 将其制作成一个应用程序包。

于 2012-03-03T05:42:21.653 回答
15

如果我采用您提供的代码并添加您得到的第一行和最后一行:

from tkinter import *

root = Tk() 
root.title("app")
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
root.geometry("550x250+%d+%d" % (screen_width/2-275, screen_height/2-125))
root.configure(background='gold')
root.lift()

mainloop()

测试一下。我按预期得到了窗口。你得到别的东西了吗?如果这可行,那么在代码中的某个地方你告诉它这样做。如果它与您的真实程序执行相同的操作,那么您的窗口管理器正在执行此操作。这是我在没有更多信息的情况下能做的最好的事情。

编辑:

在 OSX(尤其是使用 aqua 的版本)上,tkinter 的窗口可能会显示在那些已经打开的窗口后面(这里有一个错误报告:http: //bugs.python.org/issue9384 ,但由于无法修复而已关闭)。在这些情况下,添加了root.lift()命令以将窗口带到堆栈的前面,并且在所有其他情况下都是无害的。

于 2012-01-01T04:09:28.583 回答
15

对于 OS X 10.8.3,vdbuilder 和 user2435139 提供的答案的组合对我有用,即

self.root.lift()
self.root.call('wm', 'attributes', '.', '-topmost', True)
self.root.after_idle(self.root.call, 'wm', 'attributes', '.', '-topmost', False)

之前调用过

self.root.mainloop()
于 2013-07-02T23:28:59.320 回答
5

更多适用于 mac OS 用户。尽管上述解决方案似乎正确显示,但从 Finder 的角度来看,该应用程序仍处于“堆栈的末尾”。从切换器可以看出Cmd+Tab,或者只是观察 python 没有得到焦点。

用户名的解决方案解决了所有问题(同样,对于 mac OS):

import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')

也许用类似的东西包围它

import platform
if "Darwin" in platform.system():
    # apply fix
于 2013-12-16T18:32:00.933 回答
3

我修改了上述解决方案,这两行代码在 OSX 上对我有用。它将窗口带到前面,但没有使窗口表现为始终在顶部。

root.call('wm', 'attributes', '.', '-topmost', True)
root.after_idle(root.call, 'wm', 'attributes', '.', '-topmost', False)
于 2013-05-30T05:35:02.410 回答
1

如果有多个应用程序标题为“Python”的进程,则 osascript 技巧 Arnaud P 可能会出现问题此外,它不适用于 Python 3 进程(那时需要称为“Python3”。

但是,我发现了另一个可以通过使用进程 ID 来解决问题的技巧。

import os
script = 'tell application "System Events" \
  to set frontmost of the first process whose unix id is {pid} to true'.format(pid=os.getpid())
os.system("/usr/bin/osascript -e '{script}'".format(script=script))
于 2016-07-09T23:15:49.600 回答
1

就我而言,如果没有update()呼叫,则窗口不会在终端上方弹出。这就是最终的工作:

def raise_above_all(window):
    window.attributes('-topmost', True)
    window.update()
    window.attributes('-topmost', False)
于 2021-05-25T15:39:51.760 回答