如何让Tkinter应用程序跳到前面?目前,窗口出现在我所有其他窗口后面,并没有得到焦点。
我应该调用一些方法吗?
答案 0 :(得分:62)
当您说“我的其他窗口”时,假设您的意思是您的应用程序窗口,您可以在Toplevel或Tk上使用lift()
方法:
root.lift()
如果您希望窗口保持在所有其他窗口之上,请使用:
root.attributes("-topmost", True)
root
是你的Toplevel还是Tk。不要忘记-
前面的"topmost"
!
要使其临时,请在以下后禁用最右侧:
def raise_above_all(window):
window.attributes('-topmost', 1)
window.attributes('-topmost', 0)
只需传入你想要引发的窗口作为参数,这应该可行。
答案 1 :(得分:31)
如果您在Mac上执行此操作,请使用AppleEvents将重点放在Python上。例如:
import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
答案 2 :(得分:26)
在mainloop()之前添加以下行:
root.lift()
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
它对我来说非常合适。当窗口生成时,它会使窗口显示在前面,并且它不会始终保持在前面。
答案 3 :(得分:5)
关于Mac,我注意到可能存在一个问题,即如果有多个python GUI在运行,那么每个进程都会被命名为#34; Python"而AppleScript倾向于将错误的推广到前面。这是我的解决方案。我们的想法是在加载Tkinter之前和之后获取正在运行的进程ID列表。 (请注意,这些是AppleScript进程ID,它们似乎与它们的posix对应物无关。去图。)那么奇怪的人将是你的,你将那个移到最前面。 (我并不认为最后的循环是必要的,但是如果你只是得到ID为procID的每个进程,AppleScript显然会返回一个由name标识的对象,当然这是非唯一的&#34 ; Python",所以我们回到原点,除非有我缺少的东西。)
import Tkinter, subprocess
def applescript(script):
return subprocess.check_output(['/usr/bin/osascript', '-e', script])
def procidset():
return set(applescript(
'tell app "System Events" to return id of every process whose name is "Python"'
).replace(',','').split())
idset = procidset()
root = Tkinter.Tk()
procid = iter(procidset() - idset).next()
applescript('''
tell app "System Events"
repeat with proc in every process whose name is "Python"
if id of proc is ''' + procid + ''' then
set frontmost of proc to true
exit repeat
end if
end repeat
end tell''')
答案 4 :(得分:4)
最近,我在Mac上遇到了同样的问题。我使用@MagerValp
为Mac和@D K
为其他系统组合了几个答案:
import platform
if platform.system() != 'Darwin':
root.lift()
root.call('wm', 'attributes', '.', '-topmost', True)
root.after_idle(root.call, 'wm', 'attributes', '.', '-topmost', False)
else:
import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps
app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)
root.mainloop()
答案 5 :(得分:4)
某种程度上结合了各种其他方法,这适用于OS X 10.11和运行在venv中的Python 3.5.1,并且也适用于其他平台。它还通过进程ID而不是应用程序名称来定位应用程序。
from tkinter import Tk
import os
import subprocess
import platform
def raise_app(root: Tk):
root.attributes("-topmost", True)
if platform.system() == 'Darwin':
tmpl = 'tell application "System Events" to set frontmost of every process whose unix id is {} to true'
script = tmpl.format(os.getpid())
output = subprocess.check_call(['/usr/bin/osascript', '-e', script])
root.after(0, lambda: root.attributes("-topmost", False))
您可以在mainloop()
来电之前调用它,如下所示:
raise_app(root)
root.mainloop()
答案 6 :(得分:3)
在Mac OS X上,PyObjC提供了一种更清晰,更不容易出错的方法,而不是炮轰osascript:
import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps
app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)
答案 7 :(得分:0)
在macOS High Sierra上,py3.6.4,这是我的解决方案:
def OnFocusIn(event):
if type(event.widget).__name__ == 'Tk':
event.widget.attributes('-topmost', False)
# Create and configure your root ...
root.attributes('-topmost', True)
root.focus_force()
root.bind('<FocusIn>', OnFocusIn)
这个想法是将其带到最前端,直到用户与其交互,即集中精力。
我尝试了接受的答案.after_idle()
和.after()
。它们都在一种情况下失败:当我直接从PyCharm之类的IDE运行脚本时,应用程序窗口将停留在后面。
我的解决方案在遇到的所有情况下都有效。
答案 8 :(得分:0)
此答案是使一个Tkinter窗口弹出到其他Tkinter窗口的上方。
在我的应用中,我有一个大窗口toplevel
,它调用了一个较小的窗口top2
,该窗口最初显示在toplevel
的顶部。
如果用户在toplevel
窗口中单击,它将获得焦点并窒息小得多的top2
窗口,直到将toplevel
窗口从窗口中拖出为止。
解决方案是单击toplevel
中的按钮以再次启动top2
。 top2
打开功能知道它已经在运行,因此只需将其移至顶部并为其聚焦即可:
def play_items(self):
''' Play 1 or more songs in listbox.selection(). Define buttons:
Close, Pause, Prev, Next, Commercial and Intermission
'''
if self.top2_is_active is True:
self.top2.focus_force() # Get focus
self.top2.lift() # Raise in stacking order
root.update()
return # Don't want to start playing again
答案 9 :(得分:-1)
当您在Tkinter._test()函数中调用mainloop()时,有一个关于如何使Tkinter窗口成为焦点的提示。
# The following three commands are needed so the window pops
# up on top on Windows...
root.iconify()
root.update()
root.deiconify()
root.mainloop()
这是我发现的最简洁的方法,但只有Windows系统才需要它。
答案 10 :(得分:-1)
如果知道您想将目标窗口升起的窗口,则可以简单地使用tkraise
方法,并将aboveThis
参数设置为您要绘制的窗口。
from tkinter import Tk, ttk, Toplevel
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.title('Main Window')
self.state('zoomed')
self.l1 = ttk.Label(self, text='Hello World!')
self.l1.pack()
self.s = Splash()
self.s.tkraise(aboveThis=self)
class Splash(Toplevel):
def __init__(self):
Toplevel.__init__(self)
self.title('Splash Screen')
self.lift()
app = App()
app.mainloop()