如何将tkinter窗口置于其他窗口之上?

时间:2012-01-01 03:15:33

标签: python tkinter osx-lion pyobjc py2app

我正在使用带有TkinterPyObjC的Python 2,然后我正在使用py2app

程序工作正常,但是每当我打开程序时窗口都会隐藏起来,所以直到我点击底座上的图标才能显示它。

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

只是为了澄清,它不必在应用程序运行的整个过程中处于顶部。我只是需要它在其他窗口启动时处于其上。

8 个答案:

答案 0 :(得分:19)

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

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

但是窗口始终保持在其他窗口之上,直到您关闭它。对于真正的解决方案,我们需要使用py2app将其设为应用程序包。

答案 1 :(得分:14)

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

app = SampleApp()

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

app.mainloop()

答案 2 :(得分:13)

对于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()

答案 3 :(得分:11)

如果我拿走你给的代码并添加你得到的第一行和最后一行:

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()命令,在这些情况下将窗口置于堆栈的前面,并且在所有其他情况下都是无害的。

答案 4 :(得分:5)

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

来自username解决所有问题的解决方案(同样,对于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

答案 5 :(得分:3)

我修改了上面的解决方案,这两行在OSX上适用于我。它将窗口置于正面,但不会使窗口表现为Always on Top。

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

答案 6 :(得分:1)

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

但是,我发现another trick可以通过使用进程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))

答案 7 :(得分:0)

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

def raise_above_all(window):
    window.attributes('-topmost', True)
    window.update()
    window.attributes('-topmost', False)