La buona notizia è che c'è un modo per farlo.
La notizia intermedia è che non è ben documentato.
La cattiva notizia è che funziona solo su alcune piattaforme.
Le altre notizie intermedie sono che è possibile uscire da Tk su almeno alcune piattaforme.
Il modo per fare questo in Tcl/Tk è generando un evento <Motion>
con -warp 1
. La documentazione su questo è scarsa, e sparsi su poche pagine diverse (inizia da bind
), ma i dettagli sono descritti here. Fondamentalmente, è proprio questo:
event generate . <Motion> -warp 1 -x 50 -y 50
Quindi, come si fa da Tkinter?
Beh, event_generate
non è documentato da nessuna parte, e nessuno dei due è l'evento <Motion>
, o il parametro warp
... ma è abbastanza semplice da capire se si sa come mappe Tk a Tkinter:
window.event_generate('<Motion>', warp=True, x=50, y=50)
E questo in effetti genera un evento, come puoi vedere legando <Motion>
. Ecco un semplice programma di test:
from tkinter import *
root = Tk()
def key(event):
root.event_generate('<Motion>', warp=True, x=50, y=50)
def motion(event):
print('motion {}, {}'.format(event.x, event.y))
root.bind('<Key>', key)
root.bind('<Motion>', motion)
root.mainloop()
eseguirlo, fare clic sulla finestra per assicurarsi che questa è stata attivata, spostare il cursore, e vedrete che stampare qualcosa di simile:
motion 65, 69
motion 65, 70
motion 65, 71
poi premere un tasto, e sarà stampare questo:
motion 50, 50
che è grande ... se non che non può effettivamente essere in grado di spostare il cursore, nel qual caso tutto questo non fa altro che trucco Tk a pensare il cursore mosso.
Da scrematura vari forum, sembra che:
- Mac: non funziona.
- Windows: in genere funziona.
- È necessario disporre di Tk 8.4. Qualcosa o successivo. Non sono riuscito a trovare il bug per questo, ma puoi contare su 8.4 con qualsiasi installazione binario ufficiale di Windows di Python 2.7 o 3.x +.
- Inoltre, non è possibile eseguire un'app a schermo intero (che in genere non lo è, con Tk).
- Su Vista e versioni successive, in alcuni casi non funzionerà. Questo potrebbe avere qualcosa a che fare con il fatto di non possedere la sessione desktop o di non essere una sessione di console locale, o potrebbe avere a che fare con l'amministratore o altri privilegi.
- Se non funziona, è facile andare direttamente all'API Win32.
- X11 (la maggior parte di Linux, * BSD, ecc): Di solito
- tuo window manager non deve avere altri clienti disabili dalla deformazione del puntatore. Fortunatamente, non sembra essere una cosa comune da fare.
- Se si verifica questo problema, non c'è modo di aggirarlo.
- Altre piattaforme (iOS, Android, ecc.): Nessuna idea.
Per Mac, si desidera generare e inviare un evento NSMouseMoved
. Il modo più semplice per farlo è con pyobjc
(che è costruito in se si sta utilizzando Python di Apple, in caso contrario è necessario installarlo):
app = Foundation.NSApplication.sharedApplication()
event = Foundation.NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_(
Foundation.NSMouseMoved, (50, 50), 0, 0,
app.mainWindow().windowNumber(), None, 0, 0, 0.0)
app.sendEvent_(event)
Per Windows, che si desidera chiamare il SetCursorPos
API, o generare e invia un MOUSEEVENT. Il primo non funzionerà con, ad esempio, giochi DirectX; quest'ultimo potrebbe non funzionare con i desktop remoti. Per questo caso, probabilmente vuoi il primo. In entrambi i casi, il modo più semplice per farlo è quello di installare pywin32
, e poi è solo:
win32api.SetCursorPos((50, 50))
Invece di muovere il puntatore, forse rendere la posizione del controllo del puntatore la velocità * * con cui il mondo gira - più lontano dal centro più veloce è la rotazione. – unutbu
Questo è un grande suggerimento di unetbu, e usavo questo schema di controllo, ma non è facile da usare come volevo, quindi voglio qualcosa di simile a come è controllato uno sparatutto in prima persona – sam