Les événements souris et clavier dans une fenêtre graphique

Auteur.e.s
Jean-François Rey, Inra
Résumé

Sous R il est possible de récupérer les événements souris et clavier dans une fenêtre graphique afin d’interagir avec cette dernière. Nous allons voir dans cette fiche comment procéder en utilisant deux fonctions natives de R.

Tout d’abord, il faut ouvrir une fenêtre graphique qui puisse être utilisable. Sous windows x11(), sous Linux et MAC OS X (avec XQuartz) x11(type="Xlib") sinon sous MAC OS X quartz() vont respectivement ouvrir une fenêtre graphique suivant l’OS.

La fonction getGraphicsEventHandlers()

Nous allons utiliser la fonction getGraphicsEventHandlers() afin de définir les actions à entreprendre suivant les événements. En gros cette fonction permet de dire quelle est l’action à exécuter au moment du clic souris et de l’appui sur une touche clavier.

Cette fonction utilise plusieurs arguments mais les six arguments principaux sont:

  • prompt : le message affiché sur la fenêtre graphique,
  • onMouseDown : une fonction de callback pour le clic de souris,
  • onMouseMove : une fonction de callback pour le déplacement de la souris,
  • onMouseUp : une fonction de callback pour le relachement du bouton de la souris,
  • onKeybd : une fonction de callback pour l’appui sur une ou plusieurs touches du clavier.
  • which : la fenêtre graphique sur laquel on travail.

Les fonctions pour les événements de la souris prennent trois argments: function(buttons, x, y).

  • buttons est un vecteur qui contient les boutons pressés et
  • x et y sont les coordonnées du pointeur de la souris.

La fonction pour les événements clavier prend un argment function(key).

  • key est un vecteur qui contient les touches pressées.

La fonction getGraphicsEvent()

Il ne reste plus qu’à dessiner dans notre fenêtre graphique (plot) et d’appeler getGraphicsEvent().

Exemples Un petit exemple sera plus clair. Nous allons afficher dans la fenêtre graphique les événements clavier et souris.

eventSouris <- function(buttons, x, y) {
    text(buttons[1], x = x, y = y)
}

eventKeyboard <- function(key) {
    text(key[1], x = runif(1), y = runif(1))
}

On ouvre une fenêtre et on ouvre un graphique

x11(type = "Xlib")  # pour linux et pour MacOS
plot.new()

On peut ensuite lancer le code

setGraphicsEventHandlers(prompt = "Demo", onMouseDown = eventSouris, onMouseUp = NULL, 
    onKeybd = eventKeyboard)
getGraphicsEvent()

Note : suivant l’OS et les drivers, les boutons de la souris ne sont pas tous identifiés de la même manière (c’est à dire les valeurs de la variable buttons).

Pour aller plus loin, un exemple permettant de se déplacer avec la souris et de zoomer dans un graphique issu de plot.

# superplot
#
# Plot with mouse and keyboard events catching
# inspired from Duncan Murdoch examples ?getGraphEvent
#
# Mouse click and drag
# keyboard left or 4, right or 6, 8 and 2 drag
# Keyboard Up and Down, zoomin and zoomout
#
# @author Jean-Francois Rey <jean-francois.rey@paca.inra.fr>
# @date 13/04/2015
#
# superplot function
superplot <- function(..., xlim = NULL, ylim = NULL, xaxs = "r", yaxs = "r") {
    plot(..., xlim = xlim, ylim = ylim, xaxs = xaxs, yaxs = yaxs)
    startx <- 0.5
    starty <- 0.5
    prevx <- NULL
    prevy <- NULL
    usr <- par("usr")
    zoomin <- 0
    
    devset <- function() if (dev.cur() != eventEnv$which) 
        dev.set(eventEnv$which)
    
    dragmousedown <- function(buttons, x, y) {
        startx <<- x
        starty <<- y
        prevx <<- 0
        prevy <<- 0
        devset()
        usr <<- par("usr")
        eventEnv$onMouseMove <- dragmousemove
        NULL
    }
    
    dragmousemove <- function(buttons, x, y) {
        devset()
        deltax <- diff(grconvertX(c(startx, x), "ndc", "user"))
        deltay <- diff(grconvertY(c(starty, y), "ndc", "user"))
        if (abs(deltax - prevx) + abs(deltay - prevy) > 0) {
            plot(..., xlim = usr[1:2] - deltax, xaxs = "i", ylim = usr[3:4] - 
                deltay, yaxs = "i")
            prevx <<- deltax
            prevy <<- deltay
        }
        NULL
    }
    
    mouseup <- function(buttons, x, y) {
        eventEnv$onMouseMove <- NULL
    }
    
    # Keystrokes
    keydown <- function(key) {
        
        # up arrow
        if (key == "Up") {
            usr <<- par("usr")
            deltax <- (usr[2] - usr[1])/4
            deltay <- (usr[4] - usr[3])/4
            if (floor(usr[1] + deltax) < ceiling(usr[2] - deltax) & floor(usr[3] + 
                deltay) < ceiling(usr[4] - deltay) & ceiling(usr[1] + deltax) != 
                floor(usr[2] - deltax) & ceiling(usr[3] + deltax) != floor(usr[4] - 
                deltax)) {
                plot(..., xlim = c(floor(usr[1] + deltax), ceiling(usr[2] - 
                  deltax)), xaxs = "i", ylim = c(floor(usr[3] + deltay), 
                  ceiling(usr[4] - deltay)), yaxs = "i")
                zoomin <<- zoomin + 1
            }
            
        }
        
        # down arrow
        if (key == "Down") {
            
            if (zoomin >= 1) {
                usr <<- par("usr")
                zoomin <<- zoomin - 1
                deltax <- (usr[2] - usr[1])/4
                deltay <- (usr[4] - usr[3])/4
                plot(..., xlim = c(floor(usr[1] - deltax), ceiling(usr[2] + 
                  deltax)), xaxs = "i", ylim = c(floor(usr[3] - deltay), 
                  ceiling(usr[4] + deltay)), yaxs = "i")
            } else {
                plot(..., xlim = xlim, ylim = ylim, xaxs = xaxs, yaxs = yaxs)
            }
        }
        
        # left arrow or number 4
        if (key == "Left" | key == "4") {
            usr <- par("usr")
            deltax = (usr[2] - usr[1])/8
            plot(..., xlim = usr[1:2] - deltax, xaxs = "i", ylim = usr[3:4], 
                yaxs = "i")
            
            
        }
        
        # right arrow or number 6
        if (key == "Right" | key == "6") {
            usr <- par("usr")
            deltax = (usr[2] - usr[1])/8
            plot(..., xlim = usr[1:2] + deltax, xaxs = "i", ylim = usr[3:4], 
                yaxs = "i")
        }
        
        # number 8
        if (key == "8") {
            usr <- par("usr")
            deltay = (usr[4] - usr[3])/8
            plot(..., xlim = usr[1:2], xaxs = "i", ylim = usr[3:4] + deltay, 
                yaxs = "i")
        }
        
        # number 2
        if (key == "2") {
            usr <- par("usr")
            deltay = (usr[4] - usr[3])/8
            plot(..., xlim = usr[1:2], xaxs = "i", ylim = usr[3:4] - deltay, 
                yaxs = "i")
        }
        
        # q
        if (key == "q") 
            return(invisible(1))
        eventEnv$onMouseMove <- NULL
        NULL
    }
    
    setGraphicsEventHandlers(prompt = "Click and drag, hit up and Down to zoom, hit q to quit", 
        onMouseDown = dragmousedown, onMouseUp = mouseup, onKeybd = keydown)
    eventEnv <- getGraphicsEventEnv()
}

# start plotting

if (Sys.info()["sysname"] == "Linux") {
    # linux like
    dev.off()
    x11(type = "Xlib")
} else if (Sys.info()["sysname"] == "Darwin") {
    dev.off()
    # MAC os X like quartz()
    x11(type = "Xlib")
} else {
    # default windows
    windows()
}
superplot(rnorm(1000), rnorm(1000))
getGraphicsEvent()
Versions des outils utilisés
Version utilisée</strong>: R version 3.4.2 (2017-09-28)
Thèmes de la fiche
Thèmes