Как получить приложение Tkinter для перехода на передний план? В настоящее время окно появляется за всеми моими другими окнами и не фокусируется.
Есть ли какой-то метод, который я должен назвать?
Как получить приложение Tkinter для перехода на передний план? В настоящее время окно появляется за всеми моими другими окнами и не фокусируется.
Есть ли какой-то метод, который я должен назвать?
Предполагая, что вы имеете в виду окна приложений, когда вы говорите "мои другие окна", вы можете использовать метод lift()
для Toplevel или Tk:
root.lift()
Если вы хотите, чтобы окно оставалось выше всех других окон, используйте:
root.attributes("-topmost", True)
Где root
- ваш Toplevel или Tk. Не забывайте -
infront "topmost"
!
Чтобы сделать это временным, отключите верхний правый справа:
def raise_above_all(window):
window.attributes('-topmost', 1)
window.attributes('-topmost', 0)
Просто перейдите в окно, которое вы хотите поднять в качестве аргумента, и это должно сработать.
Если вы делаете это на Mac, используйте AppleEvents, чтобы сосредоточиться на Python. Например:
import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
Добавьте следующие строки перед mainloop():
root.lift()
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
Он отлично работает для меня. Это приводит к тому, что окно выходит на фронт, когда создается окно, и оно не будет всегда оставаться впереди.
Что касается Mac, я заметил, что может возникнуть проблема в том, что если будет запущено несколько графических интерфейсов python, каждый процесс будет называться "Python", и AppleScript будет стремиться продвигать на передний план не тот. Вот мое решение. Идея состоит в том, чтобы захватить список идентификаторов запущенных процессов до и после загрузки Tkinter. (Обратите внимание, что это идентификаторы процессов AppleScript, которые, похоже, не имеют никакого отношения к их сопоставлениям в столбе. Идите по фигуре.) Тогда странный человек будет вашим, и вы переместите его на передний план. (Я не думал, что цикл в конце будет необходим, но если вы просто получите каждый процесс, идентификатор которого является procID, AppleScript, очевидно, возвращает один объект, идентифицированный по имени, что, конечно же, является неистовым "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''')
Недавно у меня был тот же вопрос на 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()
В некоторой степени сочетание различных других методов, это работает на OS X 10.11 и Python 3.5.1, работающем в Вене, и должно работать и на других платформах. Он также нацелен на приложение по идентификатору процесса, а не на имя приложения.
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 OS X PyObjC предоставляет более чистый и менее подверженный ошибкам метод, чем обход в osascript:
import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps
app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)
На 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()
. Все они не работают в одном случае: когда я запускаю свой сценарий непосредственно из среды IDE, такой как PyCharm, окно приложения будет оставаться позади.
Мое решение работает во всех случаях, с которыми я столкнулся.
Здесь намек на то, как сделать окно Tkinter фокусом, когда вы вызываете mainloop() в функции Tkinter._test().
# The following three commands are needed so the window pops
# up on top on Windows...
root.iconify()
root.update()
root.deiconify()
root.mainloop()
Это самый чистый способ, который я нашел для этого, но он нужен только для систем Windows.
Если окно, которое вы хотели бы поднять целевое окно над, как известно, вы можете Simpy использовать 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()