在Shiny应用程序中,是否可以使用绑定来侦听用户按下的键?
我对JavaScript不太熟悉,但我正在寻找类似的东西:
window.onkeydown = function (e) {
var code = e.keyCode ? e.keyCode : e.which;
alert(code);
};
然后在server.R
中使用键输入,例如:
shinyServer(function(input, output) {
output$text <- renderText({
paste('You have pressed the following key:', input$key)
})
# ...
})
答案 0 :(得分:21)
您可以为按键添加侦听器。 Shiny.onInputChange
可用于将按下的键绑定到闪亮变量:
library(shiny)
runApp( list(ui = bootstrapPage(
verbatimTextOutput("results"),
tags$script('
$(document).on("keypress", function (e) {
Shiny.onInputChange("mydata", e.which);
});
')
)
, server = function(input, output, session) {
output$results = renderPrint({
input$mydata
})
}
))
您可以替换keydown
个事件:
tags$script('
$(document).on("keydown", function (e) {
Shiny.onInputChange("mydata", e.which);
});
')
答案 1 :(得分:1)
我一直在研究R软件包{keys}
,以解决此问题。基本上,它是Mousetrap javascript库的包装。这样,观察按键就很容易了:
library(shiny)
library(keys)
hotkeys <- c(
"1",
"command+shift+k",
"up up down down left right left right b a enter"
)
ui <- fluidPage(
useKeys(),
keysInput("keys", hotkeys)
)
server <- function(input, output, session) {
observeEvent(input$keys, {
print(input$keys)
})
}
shinyApp(ui, server)
此处提供更多信息:https://github.com/r4fun/keys
答案 2 :(得分:0)
如果您希望这可以用于多次按下,您可以创建一个额外的按键计数器,在按键上更新,将该值绑定到另一个变量,并观察计数器而不是键码。这是一些示例UI代码:
tags$script('
pressedKeyCount = 0;
$(document).on("keydown", function (e) {
Shiny.onInputChange("pressedKey", pressedKeyCount++);
Shiny.onInputChange("pressedKeyId", e.which);
});'
)
以及相关的服务器代码:
observeEvent(input$pressedKey, {
if(input$pressedKeyId >= 49 && input$pressedKeyId <= 57){ # numbers
values$numClick <- (input$pressedKeyId - 48);
flipNumber();
}
if(input$pressedKeyId >= 37 && input$pressedKeyId <= 40){ # arrow keys
arrowCode <- input$pressedKeyId - 37;
xInc <- ((arrowCode+1) %% 2) * (arrowCode - 1);
yInc <- ((arrowCode) %% 2) * (arrowCode - 2) * -1;
if(!any(values$click == c(-1,-1))){
values$click <- (((values$click - 1) + c(xInc, yInc) + 9) %% 9) + 1;
}
}
});
答案 3 :(得分:0)
在@jdharrison和@gringer的基础上,我想要一个监听器,该监听器不仅可以跟踪是否已按下某个键,而且还可以跟踪当前按下/按下的键。
这给了我以下内容:
library(shiny)
ui = bootstrapPage(
verbatimTextOutput("results"),
## keydown
tags$script('
downKeyCount = 0;
$(document).on("keydown", function (e) {
Shiny.onInputChange("downKey", downKeyCount++);
Shiny.onInputChange("downKeyId", e.code);
});'
),
## keyup
tags$script('
upKeyCount = 0;
$(document).on("keyup", function (e) {
Shiny.onInputChange("upKey", upKeyCount++);
Shiny.onInputChange("upKeyId", e.code);
});'
)
)
server = function(input, output, session){
keyRecords = reactiveValues()
output$results = renderPrint({
keys = reactiveValuesToList(keyRecords);
names(keys[unlist(keys)]);
})
observeEvent(input$downKey, { keyRecords[[input$downKeyId]] = TRUE });
observeEvent(input$upKey, { keyRecords[[input$upKeyId]] = FALSE });
}
shinyApp(ui = ui, server = server)
上方的关键详细信息/更改:
e.code
代替e.which
,因为这为我们提供了有关按下哪些键的更有用的描述。例如。 "KeyA"
,而不是65
。但是,这意味着我们无法区分大小写。keydown
和keyup
而不是keypress
,因为keypress
似乎超时。因此,如果您按住某个键,keypress
将处于活动状态(返回TRUE)1-2秒钟,然后变为无效状态(返回FALSE)。Shiny v1.4,R v3.6.2