我正在将 Python 2 与Tkinter
and一起使用PyObjC
,然后我正在使用py2app
.
该程序运行良好,但每当我打开程序时,窗口都会以隐藏状态启动,因此在我单击 Dock 上的图标将其调出之前,它不会出现。
有没有办法控制这一点,使窗口位于应用程序启动时打开的其他窗口之上?
澄清一下,它不必在应用程序运行的整个过程中都位于顶部。我只需要它在启动时位于其他窗口的顶部。
我知道这是一个老问题,但我发现没有人想出我所拥有的简单解决方案很奇怪,
app = SampleApp()
app.attributes('-topmost', True)
app.update()
app.attributes('-topmost', False)
app.mainloop()
我今天遇到了同样的问题。OSX 狮子 10.7.2。mainloop()
在解决问题之前添加此代码。
root.call('wm', 'attributes', '.', '-topmost', '1')
但在您关闭它之前,该窗口始终位于其他窗口之上。为了真正解决问题,我们需要使用 py2app 将其制作成一个应用程序包。
如果我采用您提供的代码并添加您得到的第一行和最后一行:
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()
命令以将窗口带到堆栈的前面,并且在所有其他情况下都是无害的。
对于 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()
更多适用于 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
我修改了上述解决方案,这两行代码在 OSX 上对我有用。它将窗口带到前面,但没有使窗口表现为始终在顶部。
root.call('wm', 'attributes', '.', '-topmost', True)
root.after_idle(root.call, 'wm', 'attributes', '.', '-topmost', False)
如果有多个应用程序标题为“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))
就我而言,如果没有update()
呼叫,则窗口不会在终端上方弹出。这就是最终的工作:
def raise_above_all(window):
window.attributes('-topmost', True)
window.update()
window.attributes('-topmost', False)