Как поставить окно tkinter поверх остальных? - PullRequest
19 голосов
/ 01 января 2012

Я использую Python 2 с Tkinter и PyObjC, а затем я использую py2app.

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

Есть ли способ контролировать это, сделать окно поверх других окон, которые были открыты при запуске приложения?

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

Ответы [ 7 ]

19 голосов
/ 03 марта 2012

Я попал в тот же вопрос сегодня. OSX LION 10.7.2. Добавьте этот код, прежде чем mainloop() решит проблему.

root.call('wm', 'attributes', '.', '-topmost', '1')

но окно всегда остается поверх остальных, пока вы не закроете его. Для реального решения нам нужно сделать из него пакет приложений с py2app.

14 голосов
/ 12 июля 2017

Я знаю, что это старый вопрос, но мне показалось странным, что никто не придумал простого решения, которое у меня было,

app = SampleApp()

app.attributes('-topmost', True)
app.update()
app.attributes('-topmost', False)

app.mainloop()
13 голосов
/ 03 июля 2013

Для 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()
11 голосов
/ 01 января 2012

Если я возьму код, который вы дадите, и добавьте первую и последнюю строку, которую вы получите:

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()

Проверьте это. Я получаю окно, как и ожидалось. Вы получаете что-то еще? Если это работает, то где-то в коде вы говорите это сделать. Если он делает то же самое, что и ваша настоящая программа, то это делает ваш оконный менеджер. Это лучшее, что я могу сделать без дополнительной информации.

Edit:

В OSX (особенно в версиях, использующих aqua) окна tkinter могут отображаться позади уже открытых (здесь есть сообщение об ошибке: http://bugs.python.org/issue9384, но оно было закрыто, так как не исправит). В этом случае добавлена ​​команда root.lift(), которая в этих случаях выводит окно в начало стека и безвредна во всех остальных случаях.

5 голосов
/ 16 декабря 2013

Больше для пользователей Mac OS. Хотя приведенные выше решения, кажется, отображаются правильно, приложение все еще находится в «конце стека» с точки зрения Finder. Как можно видеть с помощью переключателя Cmd+Tab, или просто наблюдая, что питон не получает фокус.

Решение от имя пользователя исправление всего этого (опять же, для 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
3 голосов
/ 30 мая 2013

Я модифицировал вышеупомянутое решение, и эти 2 строки работают для меня на OSX. Оно выводит окно вперед, но не заставляет окно вести себя как всегда сверху.

root.call('wm', 'attributes', '.', '-topmost', True)
root.after_idle(root.call, 'wm', 'attributes', '.', '-topmost', False)
1 голос
/ 10 июля 2016

У трюка osascript Арно P могут возникнуть проблемы, если существует более одного процесса с названием приложения «Python»; кроме того, он не будет работать для процессов Python 3 (тогда его нужно назвать «Python3».

Однако я нашел еще один прием , который может решить проблему с помощью идентификатора процесса.

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))
...