Обнаружение одиночных нажатий клавиш
Несколько раз я хотел обнаружить одиночные нажатия клавиш в R, но не смог найти ничего, кроме readline()
или подобных.
Примером может быть интерактивное построение графика или просмотр данных и возможность изменять значения параметров с помощью клавиш со стрелками и автоматически обновлять график. Конечно, я мог бы использовать readline()
и пользовательский ввод "u" вместо стрелки вверх, но я не считаю его очень элегантным.
Может ли это быть сделано с помощью команды чтения system()
stdin?
РЕДАКТИРОВАТЬ: Теперь мне сказали, что stdin также ждет ввода-инсульта, прежде чем что-либо делать, и что захватывающие нажатия клавиш сразу же являются системными и сложными для выполнения. Если кто-то знает, как это сделать на ubuntu 10.10 или в любой другой системе Linux/unix, я был бы рад узнать.
Ответы
Ответ 1
Очень зависимое от ОС решение. Сначала некоторый код C в getkey3.c:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
void mygetch ( int *ch )
{
struct termios oldt, newt;
tcgetattr ( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
*ch = getchar();
tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
return;
}
Скомпилировать для R с R CMD SHLIB getkey3.c
Это создает getkey3.so. Начать R.
> dyn.load("getkey3.so")
> .C("mygetch",as.integer(0))
затем нажмите клавишу, он должен вернуть список с первым элементом как целочисленное значение кода ASCII этого ключа. Сохраните его в переменной R, если хотите.
Работает для меня на Ubuntu, вы сами по себе для любых других ОС.
Barry
Ответ 2
Если вы не против потянуть графический набор инструментов, например tcltk или RGtk2, то пакет gWidgets может обнаруживать простые нажатия клавиш в виджетах редактирования текста. Например:
require(gWidgets)
w <- gwindow("Detect keystrokes", visible=FALSE)
e <- gedit("", cont=w)
addHandlerKeystroke(e, handler=function(h,...) {
key <- h$key
print(key)
})
visible(w) <- TRUE
Это не делает некоторые основные вещи, хотя: uparrow, downarrow могут не отображаться, модификаторы и т.д.
Ответ 3
Я не использовал R FFI в течение длительного времени, но вы можете вызвать C-функцию getchar() вместе с ним, правильно?
в типе R:?.C
Раньше я писал крошечную DLL для переноса некоторых пользовательских C-функций, а затем вызывал их с помощью .C(), однако это было в Win. Способ построения dll в Linux отличается, но я предполагаю, что способ вызова в dll тот же.
Ответ 4
Это более общее решение: C неблокирующий ввод клавиатуры.
Особенно это восстанавливает поведение терминала после того, как оно было убито или обналичено.