2012-01-09 13 views
8

Devo eseguire un controllo simile a un toggler, che esegue un'azione, quando il mouse lo supera, e esegue un'altra azione quando lascia il pulsante, ma non fa nulla mentre il mouse è finito e si muove.Come attivare un pulsante di passaggio del mouse?

mettere in chiaro, non è sufficiente per trovare semplicemente sapere se il mouse si trova su una regione o no, ma si deve eseguire del codice solo quando il mouse entra ed esce la regione. (chiarimenti richiesti di Szabolcs)

Purtroppo, l'opzione AutoAction di Button comporta in modo diverso: si cerca costantemente di eseguire l'azione mentre il mouse si muove dentro l'oggetto:

switch = False; 
Button["Hover", switch = ! switch, AutoAction -> True] 
Dynamic[switch] 

D'altra parte , un semplice comando Mouseover non può eseguire codice che viene eseguito ogni volta che il mouse lascia l'oggetto:

in = out = 0; 
Mouseover[ 
Dynamic["out", (in++) &], 
Dynamic["in", (out++) &] 
] 
Dynamic[Column[{in, out}]] 

Ho pensato che il secondo argomento di Dynamic potesse essere utilizzato per definire le azioni iniziali e finali per un oggetto Mouseover, ma non ha avuto alcun successo con questo approccio.

start = end = False; 
Dynamic[Mouseover["out", "in"], {(start = True) &, Null, (end = True) &}] 
Dynamic[Column[{start, end}]] 

Qualche idea?

+0

Quale framework stai usando, inseriscilo nella tua domanda perché potrebbe esserci qualche implementazione già disponibile piuttosto che scriverne una da zero – Noor

+0

@Noor Vedi i tag: [tag: mathematica]. È già menzionato. – Szabolcs

+0

Puoi spiegare per cosa vuoi usare questo? Hai semplicemente bisogno di scoprire se il mouse si trova su una regione o no (fattibile), o devi eseguire qualche codice * solo * quando il mouse entra (o lascia) la regione (non ho idea di come farlo) – Szabolcs

risposta

10

Si potrebbe fare qualcosa di simile:

in = 0; out = 0; 
Dynamic[Column[{in, out}]] 
Module[{over = False}, 
EventHandler[ 
    Pane[EventHandler[Dynamic[Framed[Pane[If[over, "In", "Out"], 40]]], 
    {"MouseMoved" :> If[Not[over], over = True; in++]}, 
    PassEventsUp -> False], ImageMargins -> 4], 
    {"MouseMoved" :> If[over, over = False; out++]}]] 

Quello che fa è per avvolgere la regione per la quale si desidera registrare le entrate e le uscite in una regione leggermente più grande con Pane. Sia la regione interna che la regione esterna hanno un EvenHandler che registra i movimenti del mouse. Impostando PassEventsUp->False per l'interno EventHandler, gli eventi "MouseMoved" vengono passati all'esterno EventHandler solo se il puntatore del mouse si trova sopra la regione esterna ma non sopra la regione interna.

+0

Soluzione elegante, stavo pensando sulla stessa linea. Sembra esserci un piccolo problema con i movimenti del mouse molto veloci non registrati, ma suppongo che capiti anche a un semplice Mouseover. –

+0

Grazie. Nella mia soluzione, ho scelto un margine di 4 punti attorno alla regione interna. Poiché la posizione del mouse viene campionata a una determinata velocità (circa 20 volte al secondo se ricordo correttamente) potrebbe accadere che si salti questo margine tra due campionamenti se si muove il mouse abbastanza velocemente. Aumentare 'ImageMargins' nel codice qui sopra dovrebbe risolvere questo problema. – Heike

+0

Davvero fantastico! Questo dovrebbe essere nei documenti. – telefunkenvf14

Problemi correlati