R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。
R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。
要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。
关于作者:
- 张丹(Conan), 程序员Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: bsspirit@gmail.com
转载请注明出处:
http://blog.fens.me/r-keyboard-mouse/
前言
在使用R语言的过程中,很多的技术点会被我们的忽略,这些经常被忽略的技术点大都和数据无关。但反过来讲,如果你能掌握这些技术点,你开发R语言应用会让人觉得Amazing!
本文我们就来聊一下R语言的键盘和鼠标事件。
目录
- R语言图形事件
- 图形事件API
- 键盘事件
- 鼠标事件
1. R语言图形事件
R语言中,应用最广的一类功能是画图,我们会经常使用R语言作图的API,像plot(),barplot(),points(),lines()等。每次调用plot()函数,R运行时环境都会启动一个新的图形设备(Graphics Device)。这个新打开的图形设备,除了会显示我们的定义的图形,还内置了一套事件管理器,可以监听键盘和鼠标事件,实现与图形设备的通信。
这个事件管理器在grDevices包中定义,并作为当前环境的父环境应用于用户环境空间中,关于环境空间的解释,请参考文章,http://blog.fens.me/r-environments/。
试想一下,如果画图程序可以实现与鼠标和键盘通信,那么静态图片也就可以与用户进行交互了。掌握这个功能,R语言将不仅仅用于离线分析,还可以用来做时时应用,聊天工具或者是游戏。
接下来,就让我们开始了解R语言的图形事件API。
2. 图形事件API
图形事件API函数只有4个:
- setGraphicsEventHandlers, 注册图形事件,包括键盘事件和鼠标事件(按下,释放,移动)。
- getGraphicsEvent, 启动图形事件监听器,开始监听。
- setGraphicsEventEnv, 设置图形设备和环境空间,默认为当前图形设备和当前环境空间。
- getGraphicsEventEnv, 获取图形设备,默认为当前图形设备。
要在图形设备中接受鼠标和键盘事件,我们就需要通过setGraphicsEventHandlers()函数,把键盘和鼠标事件注册到图形设备中。
我们首先,看一下这个函数的定义。
> setGraphicsEventHandlers
function (which = dev.cur(), ...)
setGraphicsEventEnv(which, as.environment(list(...)))
<bytecode: 0x000000000b321d20>
<environment: namespace:grDevices>
通过定义我们只能看到 setGraphicsEventHandlers() 又调用了setGraphicsEventEnv(),用来设置图形设备,而setGraphicsEventHandlers()的参数都用“…”隐藏了。
接下来,我们再查看 getGraphicsEvent()函数的定义。我可以发现getGraphicsEvent()函数的参数可用于事件绑定,并且 getGraphicsEvent()的参数,实际上是用来传给setGraphicsEventHandlers()函数的。
> getGraphicsEvent
function (prompt = "Waiting for input", onMouseDown = NULL, onMouseMove = NULL,
onMouseUp = NULL, onKeybd = NULL, consolePrompt = prompt)
{
if (!interactive())
return(NULL)
if (!missing(prompt) || !missing(onMouseDown) || !missing(onMouseMove) ||
!missing(onMouseUp) || !missing(onKeybd)) {
setGraphicsEventHandlers(prompt = prompt, onMouseDown = onMouseDown,
onMouseMove = onMouseMove, onMouseUp = onMouseUp,
onKeybd = onKeybd)
}
.External2(C_getGraphicsEvent, consolePrompt)
}
<bytecode: 0x0000000005c4bd40>
<environment: namespace:grDevices>
参数说明:
- prompt, 文字提示
- consolePrompt, 在终端中的文字提示
- onMouseDown, 鼠标事件,按下鼠标按键
- onMouseUp, 鼠标事件,释放鼠标按键
- onMouseMove, 鼠标事件,鼠标移动
- onKeybd, 键盘事件,按下键盘
这样,通过getGraphicsEvent()函数的封装,我们可以绑定鼠标事件和键盘事件的操作了。
3. 键盘事件
说完知识点和API,下面我们就要动手写点程序了。
系统环境:
- Win7 64bit
- R: 3.0.1 x86_64-w64-mingw32/x64 b4bit
先做一个键盘事件的小程序,要求:
- 1. 利用R语言画图,根据键盘输入显示对应的文字。
- 2. 每按一下键盘,输出一个字母在屏幕上面。
- 3. 按ctrl+c时,停止键盘事件。
左边为R语言程序后台,每次键盘输入,打印一行日志,右边图形设置中间的文字会跟着变化。
注:程序不能在RStudio中运行。
代码现实如下:
# 字母工具
letter<-function(){
# 画图函数
draw<-function(label='',x=0,y=0){
plot(x,y,type='n')
text(x,y,label=label,cex=5)
}
# 键盘事件
keydown<-function(K){
if (K == "ctrl-C") return(invisible(1))
print(K)
draw(K)
}
# 画图
draw()
# 注册键盘事件,启动监听
getGraphicsEvent(prompt="Letter Tool",onKeybd = keydown)
}
#启动程序
letter()
实现代码还是比较简单地。接下来,我们加上鼠标的事件,实现一个稍微复杂点的例子。
4. 鼠标事件
R语言中,图形设备的鼠标事件,包括3种类型: 鼠标移动, 鼠标按下(左键,右键,滚轮),鼠标释放。
我们设计一个应用,要求:
- 1. 利用R语言画图,根据鼠标事件指定图形的位置和形状。
- 2. 每移动一下鼠标,左下角输出鼠标所在的坐标,同时一个默认的图形随鼠标移动。
- 3. 当鼠标按下时,会在当前坐标出现一个图形,左键对应正方形,滚轮对应用圆形,右键对应三角形。
- 4. 按q时,停止监听事件。
代码现实如下:
mouse <- function() {
# 设置画布无边
par(mai=rep(0,4),oma=rep(0,4))
# 初始化的点
ps<-data.frame(x=c(0.5),y=c(0.5),col=c(2),pch=c(15))
# x,y为鼠标坐标
draw<-function(x=0,y=0){
plot(0,0,xlim=c(0,1),ylim=c(0,1),type='n',xaxs="i", yaxs="i")
abline(h=0.5,col="gray60") # 水平线
abline(v=0.5,col="gray60") # 垂直线
points(ps$x,ps$y,pch=ps$pch,cex=2,col=ps$col) # 实点标点
points(x,y,pch=15,cex=2,col=colors()[ps$col]) # 鼠标坐标点
text(0.25,0.015,label=paste(x,y,sep=",")) # 鼠标坐标
}
# 鼠标按键监听
# 当鼠标按键,会增加一个实点
# buttons,0是左键,1是滚轮,2是右键
mouseDown <- function(buttons, x, y) {
print(paste("down",buttons,x,y))
# 形状设置
shape<-15
if(buttons==1) shape<-16
if(buttons==2) shape<-17
# 增加实点
ps<<-rbind(ps,data.frame(x=c(x),y=c(y),pch=c(shape),col=round(runif(1,2,500))))
#print(ps)
draw(x,y)
}
# 鼠标移动监听
mouseMove <- function(buttons, x, y) {
print(paste("move",buttons,x,y))
draw(x,y)
}
# 鼠标按键释放监听
mouseup <- function(buttons, x, y) {
print(paste("up",buttons,x,y))
draw(x,y)
}
# 键盘按键监听
keydown <- function(key) {
if (key == "q") return(invisible(1))
}
# 画初始坐标
draw()
# 注册事件
getGraphicsEvent(prompt="mouse",onMouseDown=mouseDown,onMouseMove=mouseMove,onMouseUp=mouseup,onKeybd=keydown)
}
# 启动程序
mouse()
通过对R语言图形设备的事件监控,我们就可以轻松现实鼠标和键盘与程序的交互了,是不是很有意思呢。!!下一篇文章,让我们来动手做个游戏吧。