どのようにフロントへTkinterのウィンドウジャンプを作るには?
質問
どのように私はTkinterのアプリケーションが前面にジャンプするのですか?現在、窓はすべて私の他のウィンドウの後ろに表示され、フォーカスを取得していません。
私が呼び出しされなければならないいくつかの方法がありますか?
解決
あなたは「私の他のウィンドウ」と言うとき、あなたはトップレベルまたはTkの上lift()
メソッドを使用することができ、アプリケーションのウィンドウを意味すると仮定します:
root.lift()
あなたは、ウィンドウを他のすべてのウィンドウの上に滞在したい場合は使用します:
root.attributes("-topmost", True)
どこroot
はあなたのトップレベルまたはTkのです。 -
の"topmost"
のインフロントを忘れないでください!
、のそれはの一時的な作りの後に最上位の権利を無効にするには:
def raise_above_all(window):
window.attributes('-topmost', 1)
window.attributes('-topmost', 0)
ちょうどあなたが引数として提起したいウィンドウに渡し、これは動作するはずです。
他のヒント
あなたは、Mac上でこれをやっている場合は、Pythonのにフォーカスを与えることのAppleEventsを使用しています。例えばます:
import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
)(メインループの前に次の行を追加します:
root.lift()
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
これは私のために完璧に動作します。これは、ウィンドウが生成されたときに、ウィンドウが前面に来ます、そしてそれは、常に前にあり続けるなくなります。
マックについては、私はそれで問題がある可能性があります気づいた、すべてのプロセスは「パイソン」と命名され、AppleScriptは、フロントに間違ったものを促進する傾向があります。ここに私のソリューションです。アイデアは、あなたがTkinterのをロードする前と後のプロセスIDを実行しているのリストをつかむことです。 (これらは彼らのPOSIXの対応とは関係を負わないように見えるのAppleScriptプロセスIDであることに注意してください。図を移動します。)その後、仲間外れはあなたのものよ、あなたは1つが最前面することを移動します。そう、(私は最後にそのループが必要であろうとは思いませんでしたが、あなたは、単にそのID procIDをあるすべてのプロセスを取得する場合、AppleScriptは明らかに、もちろん「パイソン」という非ユニークな名前で識別される1つのオブジェクトを返します私が欠けている何かがありますしない限り、私たちは振り出しに戻っています。)
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 OS X PyObjCでは、osascriptをに砲撃よりクリーンでエラーが発生しにくい方法を提供します:
import os
from Cocoa import NSRunningApplication, NSApplicationActivateIgnoringOtherApps
app = NSRunningApplication.runningApplicationWithProcessIdentifier_(os.getpid())
app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)
最近、私はMac上で同じ質問がありました。私は、他のシステムのためのMac用@MagerValp
と@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()
やや様々な他の方法の組み合わせの、これはvenvで動作している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()
MacOSのハイシエラには、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から直接、私のスクリプトを実行すると、アプリケーションのウィンドウの背後に滞在します。
私のソリューションは、私が遭遇したすべてのケースで動作します。
Tkinter._test()関数の中で)あなたがメインループ(呼び出すとき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システムのために必要だ。
ウィンドウがあなたのターゲットウィンドウの上に上げたい場合は、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()