私はPythonでTkinter UIを使ってプログラムを書いています。私はタイトルバーのない小さなウィンドウを持っていたい。このウィンドウにはキーボード入力が必要です。私はこれがEntryウィジェットの形であるのか、KeyPressへのバインディングであるのかはわかりません。 overrideredirect(True)
は、通常、タイトルバーが無効になる方法です。残念ながら、(Windowsを除く)、これは多くのイベントが受信されるのを妨げるようです。私はこの問題を説明するために、このコードを書いた:TkinterのoverrideredirectがMacとLinuxで特定のイベントを防ぎます
#!/usr/bin/env python
from __future__ import print_function
import Tkinter
class AppWindow(Tkinter.Tk):
def __init__(self, *args, **kwargs):
Tkinter.Tk.__init__(self, *args, **kwargs)
self.overrideredirect(True)
self.geometry("400x25+100+300")
titleBar = Tkinter.Frame(self)
titleBar.pack(expand = 1, fill = Tkinter.BOTH)
closeButton = Tkinter.Label(titleBar, text = "x")
closeButton.pack(side = Tkinter.RIGHT)
closeButton.bind("<Button-1>", lambda event: self.destroy())
self.bind("<KeyPress>", lambda event: print("<KeyPress %s>" % event.char))
self.bind("<Button-1>", lambda event: print("<Button-1>"))
self.bind("<Enter>", lambda event: print("<Enter>"))
self.bind("<Leave>", lambda event: print("<Leave>"))
self.bind("<FocusIn>", lambda event: print("<FocusIn>"))
self.bind("<FocusOut>", lambda event: print("<FocusOut>"))
if __name__ == "__main__":
app = AppWindow()
app.mainloop()
これはそれがそれらを受信したときに一般的なイベントの名前を出力します(タイトルバーなしで)小さなウィンドウを作成します。私はこのスクリプトをWindows 7、Mac OSX(El Capitan)、およびUbuntu 14.04.1で実行しました。私は仮想マシン(VMWare)でUbuntuだけを走らせました。
Windowsでは、これは期待どおりに動作しているようです。私のコードがテストするすべてのイベントを受け取ることができます。
Ubuntuのでは、Tkinterのウィンドウは
<Enter>
、<Leave>
、および<Button-1>
予想通りのイベントが、<KeyPress>
、<FocusIn>
を受け取り、<FocusOut>
が受信されることはありません。実際には、ウィンドウがクリックされた後でも、フォーカスを持つ最後のウィンドウはキープレスを受け取り続けます。 OSXで、Tkinterの窓は、予想通り
<Button-1>
イベントを受信しますが、<KeyPress>
、<FocusIn>
、および<FocusOut>
が受信されることはありません。フォーカスを持つ最後のウィンドウは、Ubuntuのようなキーの押下を受け続けることはありません。<Enter>
と<Leave>
イベントはちょっと変な動作をします。<Enter>
イベントは、ウィンドウがクリックされるまで受信されません。その後、<Leave>
イベントが発生すると、再度<Enter>
イベントを受信するには、ウィンドウを再度クリックする必要があります。
私もちょうど__init__
機能の終了前self.focus_force()
を試してみました。これにより、プログラムの起動時にウィンドウが<FocusIn>
イベントを受信しますが、それ以上のイベントは受信されません。<KeyPress>
、<FocusIn>
、または<FocusOut>
イベントは受信されません。
最終的に私の質問はこれです:タイトルバーを隠す方法はありますか?OSXとLinuxでキーボード入力を受け続けますか?
この同じ問題を扱う他の質問があります。
- python tkinter overrideredirect; cannot receive keystrokes (Linux)
- root.overrideredirect and <Any-KeyPress> binding
- How to bind Tkinter destroy() to a key in Debian?
受け入れ答えはself.attributes('-fullscreen', True)
を使用することです、私は、小さな小さなウィンドウをしませ欲しいと私のために動作しません。これらの3つの質問で全画面アプリケーション。
もう1つの質問があります:Tkinter overrideredirect no longer receiving event bindingsです。これは私の質問に非常に近いと思われますが、詳細は少なく、答えはありません。
アップデート:私は私の問題の根底にあるメカニズムを調べるしようとしてきました。私はTkinterがTcl/Tkのラッパーであることを知っているので、私はTclで自分のコードを書き直そうと思っていました。私は実際のTclを知らないが、私は(多かれ少なかれ)に管理さだと思う私はPythonを翻訳:
#!/usr/bin/env wish
wm overrideredirect . True
wm geometry . "400x25+100+300"
bind . <KeyPress> {puts "<KeyPress %K>"}
bind . <Button-1> {puts "<Button-1>"}
bind . <Enter> {puts "<Enter>"}
bind . <Leave> {puts "<Leave>"}
bind . <FocusIn> {puts "<FocusIn>"}
bind . <FocusOut> {puts "<FocusOut>"}
私はWindowsとMac OSXでの結果のプログラムを試してみました。 Windowsでは、私は<KeyPress>
イベントを受け取りましたが、OSXで私はしませんでした。 wm overrideredirect . True
行がないと、OSXは<KeyPress>
イベントを受信します。したがって、この問題はPythonではなくTcl/Tkのように見えます。
「mainloop」とそれに再度アクセスする方法を無効にしますか?Binding(key listen)はサブ要素で処理します。 'listener'が' frozen'の場合、 'ghost'アプリケーションを取得しました。 – dsgdfg
トリック:[X]ボタンをメインループにしてください( 'deiconify()')! – dsgdfg