如何使Tkinter应用程序跳转到前台?目前,窗口显示在我的所有其他窗口后面,并且没有焦点。
是否有一些我应该调用的方法?
假设你所说的“我的其他窗口”是指你的应用程序窗口,你可以在Toplevel或Tk上使用lift()
方法:
root.lift()
如果你想让窗口保持在所有其他窗口的上方,请使用:
root.attributes("-topmost", True)
请注意,在root
参数中传入你的 Toplevel
或 Tk
对象。不要忘记在"topmost"
之前加上-
符号!
如果想要临时取消置顶,可以在操作后立即将topmost
设置为False
:
def raise_above_all(window):
window.attributes('-topmost', 1)
window.attributes('-topmost', 0)
只需将您想要提升的窗口作为参数传递即可,这应该可以起作用。
在主循环(mainloop())之前添加以下行:
root.lift()
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
这对我来说完美无缺。它使窗口在生成时前置,并且不会一直保持在前面。
如果您正在Mac上进行操作,请使用AppleEvents将焦点放在Python上。例如:
import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
root = tk.Tk()
之后,root.mainloop()
之前完成。此外,对于我的 Anaconda 安装,它必须是小写的 process "python"
。 - user3148185import 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''')
import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps
app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)
这种方法有点像其他几种方法的结合体,在运行OS X 10.11和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()
最近,我在Mac上遇到了同样的问题。我结合了多个答案,其中包括@MagerValp
提供的Mac系统方案,以及@DK
提供的其他系统方案:
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()
在Tkinter._test()函数中有一个提示,可以使Tkinter窗口在调用mainloop()时获得焦点。
# The following three commands are needed so the window pops
# up on top on Windows...
root.iconify()
root.update()
root.deiconify()
root.mainloop()
这是我找到的最干净、最合适的做法,但它仅适用于Windows系统。
这个答案是为了让一个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
还需要一行(对于Python 3.11和tkinter 8.6):
def lift_window(window):
window.attributes('-topmost', True)
window.update_idletasks() # get window on top
window.attributes('-topmost', False) # prevent permanent focus
window.focus_force() # focus to the window