Я работаю над проектом на малине pi в Qt. У меня есть клавиатура usb и считыватель магнитных карт USB (который читается как клавиатура). Мне нужно уметь изолировать вход для считывателя карт, чтобы он не мог использоваться для заполнения обычного текстового поля и читался по-разному для информации о кредитной карте. Оба, кажется, имеют свои файлы в/dev как элементы hidraw, хотя их упорядочение является случайным. Есть ли способ изолировать один от другого программным путем? Заранее благодарю за любую помощь!Qt C++ изолировать клавиатуру
3
A
ответ
0
Насколько я могу найти, нет возможности использовать Qt для определения источника события. К сожалению, также нет способа использовать udev для изменения узла ядра, поэтому нет возможности предотвратить использование Qt его входным файлом. Единственное, что я мог сделать, это захватить входной файл и получить эксклюзивный доступ, таким образом вырезая Qt. Я сделал это в отдельном потоке, который ждет ввода с устройства, а затем сообщает об этом с помощью сигнала. Я отправлю куски кода для QThread для тех, кого это интересует.
#include <QObject>
#include <QThread>
#include <QDebug>
#include <qplatformdefs.h>
#include "stdio.h"
#include "constants.h"
#include "linux/input.h"
namespace KeyboardConstants {
static const QString keys[] = {"","","1","2","3","4","5","6","7","8","9","0",
"-","=","","","q","w","e","r","t","y","u",
"i","o","p","[","]","","","a","s","d","f",
"g","h","j","k","l",";","'","`","","\\","z",
"x","c","v","B","n","m",",",".","/","","","",
" ","",""};
static const QString shiftKeys[] = {"","","!","@","#","$","%","^","&","*","(",")",
"_","+","","","Q","W","E","R","T","Y","U",
"I","O","P","{","}","","","A","S","D","F",
"G","H","J","K","L",":","\"","~","","|","Z",
"X","C","V","B","N","M","<",">","?","","",""};
}
QString input = "";
void ccWatcher::run()
{
struct input_event ev[1];
int fevdev = -1;
int size = sizeof(struct input_event);
int rd;
char name[256] = "Unknown";
bool shift = false;
QString device = "/dev/input/by-id/usb-XXXX";
fevdev = open(device.toStdString().c_str(), O_RDONLY);
if (fevdev >= 0) {
ioctl(fevdev, EVIOCGNAME(sizeof(name)), name);
// Gain exclusive access to the input_event file
ioctl(fevdev, EVIOCGRAB, 1);
while (1)
{
// Shouldn't happen, but you never know
if ((rd = read(fevdev, ev, size)) < size) {
break;
}
// Make sure the type is "key" and the value is 1
if (ev[0].type == 1 && ev[0].value == 1) {
// 28 and 96 are the codes for 'enter'
if (ev[0].code != 28 && ev[0].code != 96) {
// 42 and 54 are the codes for shift
if (ev[0].code == 42 || ev[0].code == 54) {
shift = true;
} else {
if (shift) {
input.append(KeyboardConstants::shiftKeys[ev[0].code]);
shift = false;
} else input.append(KeyboardConstants::keys[ev[0].code]);
}
} else {
emit ccReadin(input);
input = "";
}
}
}
}
}
Попробуйте 'evrouter'. Он может фильтровать входные события на основе имени устройства. (если вы используете полную среду X) – Velkan
Darn, я не в среде X, так как я использую EGLFS. Спасибо хоть! – Nick
Может быть, он использует 'evdev' в любом случае. И я видел, что вы можете передать переменную среды, чтобы установить, какое устройство использовать. Или, возможно, EGLFS использует 'libinput'. В любом случае есть инструменты командной строки в 'evdev' и' libinput', чтобы определить имена устройств и прочитать их. Для просмотра того, что использует Qt, существует переменная 'QT_LOGGING_RULES = qt.qpa.input = true'. – Velkan