2016-01-03 28 views
12

bazı olayları önler. Başlık çubuğu olmayan küçük bir pencereye sahip olmak istiyorum. Bu pencere klavye girişi almalıdır. Bunun bir Giriş widget'ı şeklinde mi yoksa sadece KeyPress'e mi bağlandığı konusunda seçici değilim. overrideredirect(True) genellikle başlık çubuğunun nasıl devre dışı bırakıldığıdır. Ne yazık ki, (Windows dışında), bu birçok olayın alınmasını engelliyor gibi görünüyor.Tkinter en overrideredirect bir Tkinter UI ile Python bir program yazıyorum Mac ve 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() 

Bu (başlık çubuğu ile) biraz penceresi oluşturur onları aldığında ortak olayların adını yazdıran: Sorunu göstermek için bu kodu yazdım. Bu komut dosyasını Windows 7, Mac OSX (El Capitan) ve Ubuntu 14.04.1'de çalıştırdım. Sanal makinede sadece Ubuntu'yu (VMWare) çalıştırdım.

  • Windows'ta, beklendiği gibi çalışıyor gibi görünüyor. Kodumun test ettiği tüm olaylar alınabilir.

  • Ubuntu yılında Tkinter penceresi <Enter>, <Leave> ve <Button-1> beklendiği gibi olayları ancak <KeyPress>, <FocusIn> alır ve <FocusOut> alınan asla. Hatta, pencereye tıklandıktan sonra bile, odağı olan son pencere, tuşa basmaya devam eder.

  • OSX yılında Tkinter pencere <Button-1> beklendiği gibi olayları ancak <KeyPress>, <FocusIn> alır ve <FocusOut> alınan asla. Odaklı son pencere Ubuntu'daki gibi tuşa basmaya devam etmiyor. <Enter> ve <Leave> olaylar tuhaf biraz davranırlar. Pencere tıklandığında kadar <Enter> olay alınmadı. <Leave> olay meydana yerleştirdikten sonra da, pencere başka <Enter> olayını almak için tekrar tıkladım gerekir.

Ben de sadece __init__ fonksiyonunun sona ermeden self.focus_force() çalıştık. Program başladığında Bu <FocusIn> olayını almak için pencereyi neden olur, ancak başka <KeyPress>, <FocusIn> veya <FocusOut> olaylar almadım edilir. başlık çubuğunu gizlemek ama OSX ve Linux klavye girişi almaya devam etmek herhangi bir yolu var olup:

Sonuçta, sorum şudur?


Bu aynı sorunla ilgilenen diğer bazı soruların farkındayım.

kabul cevap self.attributes('-fullscreen', True) kullanmaktır, ben, minik bir pencere değil istemek benim için çalışmaz: Bu üç soruya ise tam ekran uygulaması. Tkinter overrideredirect no longer receiving event bindings:

bir başka soru var. Bu benim soruma çok yakın görünüyor, ancak daha az ayrıntı sağladı ve hiçbir cevabı yok.


Güncelleme: benim sorunun altında yatan mekanizmayı araştırmak için teşebbüs edilmiştir. Tkinter'in Tcl/Tk etrafında bir sarıcı olduğunu biliyorum, bu yüzden kodumu Tcl'de yeniden yazmayı denediğimi düşündüm. Benim Python çevirmek Gerçekten Tcl bilmiyorum, ama ben (az ya da çok) başardı düşünüyorum:

#!/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>"} 

Ben Windows ve Mac OSX ile sonuçlanan programı denedik. Windows'da, <KeyPress> olaylarını aldım, ancak OSX'te ben yapmadım. wm overrideredirect . True hattı olmadan, OSX <KeyPress> olayları almak yok. Bu nedenle bu sorunun Python ile değil Tcl/Tk ile olduğu anlaşılıyor.

+0

'mainloop' ve' yeniden nasıl erişileceğini devre dışı bırakacaksınız '' Bağlama (anahtar dinleme) alt öğelerle çalışır. Dinleyici 'donmuşsa, bir 'hayalet' uygulaması kazandın. – dsgdfg

+0

A püf noktaları: mainloop olarak [X] düğmesine olun (böylece 'deiconify()')! – dsgdfg

cevap

2

bu durum için Tk bir hata raporu sundular.

Sen penceresinden süslemeleri kaldırmak için devilspie programını kullanabilirsiniz. Pencerenize belirli bir ad vermek için wm title . myname komutunu kullanın ve bu adı aşağıdaki devilspie yapılandırma bölümünde kullanın. Programınızdan overrideredirect komutunu kaldırın. Bu testi (Tk programı olarak) test ettim ve oyulmamış pencere hala & vb. Bindings tuşlarını almaya devam edecektir.

devilspie'un bir daemon işlemi olarak yazıldığını ve etkin kaldığını unutmayın. Olay başladığında daemon öldürülür ve yapılan pencere değişiklikleri hala geçerli olacaktır. Ya da çalışan bırakılabilir, ve pencere aktif hale her zaman, devilspie yapılandırma uygulanacaktır.

(if (is (application_name) "t.tcl") 
    (begin (undecorate))) 
+0

Err ... bu Linux için. Mac için eşdeğer bir program olup olmadığını bilmiyorum. –

+0

Teşekkürler, benim için mükemmel çalışıyor (LXDE ile Archlinux). –

+0

overrideredircct içeren bir pencere kasten önemli olayları alamayan böylece odak almaktan engellenir ve: http://core.tcl.tk/tk/artifact/7892c68f49012d2d71222ae0e312a1e7dc69a801?txt=1&ln=51-64 Bu çizgi ve yorumdur antik ve kaldırmak mümkün olabilir. Yine de emin değilim. – Hugge