2013-07-21 14 views
10

Sto scrivendo un'applicazione in Python con la struttura della GUI di Tkinter. Ascolta gli eventi di tastiera e mouse, quindi deve essere attivo. Quando è lanciato da un terminale in Ubuntu, il seguente codice funziona:Focus della finestra di Tkinter su Mac OS X

from Tkinter import * 

root = Tk() 
root.focus_force() 

def key(event): 
    print "pressed", event.char 

def callback(event): 
    print "clicked at", event.x, event.y 

frame = Frame(root, width=100, height=100) 
frame.bind("<Key>", key) 
frame.bind("<Button-1>", callback) 
frame.pack() 
frame.focus_force() 

root.mainloop() 

Tuttavia, quando lanciato da un terminale in Mac OS X 10.8.4 (magazzino Python 2.7.2), messa a fuoco viene trattenuto dal terminale emulatore finché l'utente non fa clic sulla finestra. Qualcuno sa di una soluzione alternativa per questo?

risposta

9

Ho provato questo e ha funzionato bene per me:

from os import system 
from platform import system as platform 

# set up your Tk Frame and whatnot here... 

if platform() == 'Darwin': # How Mac OS X is identified by Python 
    system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''') 

Naturalmente, che sarà portare la vostra intera applicazione alla parte anteriore, non solo una finestra specifica, ma dopo aver fatto ciò, è possibile utilizzare focus_force() su una specifica finestra o frame e questo verrà spostato per diventare il primo di tutte le finestre dell'applicazione.

Per chi fosse interessato, non ho scritto personalmente la chiamata system(). L'ho trovato in this thread on SourceForge.

Il fatto che ho messo la chiamata system() all'interno di un blocco if che verifica questa è in esecuzione su OS X rende la piattaforma di soluzione cross - la mia comprensione è che focus_force() lavori su tutte le altre piattaforme esattamente come si desidera, e solo l'esecuzione dopo l'invocazione system() non causerebbe alcun problema anche in OS X.

+1

Un trucco facile da fare su go-it-work-now :-). Grazie! – yair

-1

Do wait_visibility e event_generate help?

es. qualcosa di simile -

from Tkinter import * 

root = Tk() 

def key(event): 
    print "pressed", event.char 

def callback(event): 
    print "clicked at", event.x, event.y 

frame = Frame(root, width=100, height=100) 
frame.bind("<Key>", key) 
frame.bind("<Button-1>", callback) 
frame.pack() 

frame.focus_set() 

root.wait_visibility() 
root.event_generate('<Button-1>', x=0, y=0) 

root.mainloop() 
+0

Sfortunatamente non –

2

è venuto qui a chiedermi la stessa domanda, ma ho trovato questa risposta suona saggia da Kevin Walzer che suggerisce di utilizzare py2app:

Sì, questo è il comportamento standard per OS X. Esecuzione un'app nel Terminal mantiene l'attenzione nel Terminale a meno che non si passi facendo clic su Windows. Il comportamento della scheda Comando è determinato dal sistema di finestre e non da un nuovo processo generato da .

Il modo per aggirare questo è quello di avvolgere l'applicazione in un pacchetto Mac standard utilizzando py2app. L'utente Mac medio non avvierà un gioco basato su Python dalla riga di comando.

Kevin

(da https://groups.google.com/forum/#!topic/comp.lang.python/ZPO8ZN5dx3M)

+0

È anche possibile utilizzare [pyinstaller] (http://www.pyinstaller.org/). Mi piace perché posso creare sia i bundle per Mac App che i file eseguibili di Windows. – Fiver