Подтвердить что ты не робот

Как заставить окно Tkinter перейти на передний план?

Как получить приложение Tkinter для перехода на передний план? В настоящее время окно появляется за всеми моими другими окнами и не фокусируется.

Есть ли какой-то метод, который я должен назвать?

4b9b3361

Ответ 1

Предполагая, что вы имеете в виду окна приложений, когда вы говорите "мои другие окна", вы можете использовать метод 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)

Просто перейдите в окно, которое вы хотите поднять в качестве аргумента, и это должно сработать.

Ответ 2

Если вы делаете это на Mac, используйте AppleEvents, чтобы сосредоточиться на Python. Например:

import os

os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')

Ответ 3

Добавьте следующие строки перед mainloop():

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

Он отлично работает для меня. Это приводит к тому, что окно выходит на фронт, когда создается окно, и оно не будет всегда оставаться впереди.

Ответ 4

Что касается 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''')

Ответ 5

Недавно у меня был тот же вопрос на 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()

Ответ 6

В некоторой степени сочетание различных других методов, это работает на 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()

Ответ 7

В Mac OS X PyObjC предоставляет более чистый и менее подверженный ошибкам метод, чем обход в osascript:

import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps

app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)

Ответ 8

На 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, окно приложения будет оставаться позади.

Мое решение работает во всех случаях, с которыми я столкнулся.

Ответ 9

Здесь намек на то, как сделать окно 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.

Ответ 10

Если окно, которое вы хотели бы поднять целевое окно над, как известно, вы можете 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()