2017-02-16 16 views
3

Qt의 라즈베리 파이 프로젝트에서 작업하고 있습니다. USB 키보드와 USB 마그네틱 카드 판독기 (키보드로 읽음)를 꽂았습니다. 일반 텍스트 상자를 채우는 데 사용할 수 없으며 다르게 읽혀 지도록 카드 판독기 입력을 격리 할 수 ​​있어야합니다. 신용 카드 정보. 두 파일 모두 hidraw 항목으로/dev에 파일이있는 것처럼 보이지만 순서는 임의적입니다. 프로그래밍 방식으로 다른 프로그램과 분리 할 수있는 방법이 있습니까? 어떤 도움을 주셔서 미리 감사드립니다!Qt C++ 키보드 분리

+0

'evrouter'를 사용해보세요. 장치 이름을 기반으로 입력 이벤트를 필터링 할 수 있습니다. (전체 X 환경을 사용하는 경우) – Velkan

+0

EGLFS를 사용하고 있기 때문에 X 환경에 있지 않습니다. 그래도 고마워! – Nick

+1

어쨌든'evdev'를 사용했을 수도 있습니다. 그리고 환경 변수를 전달하여 사용할 장치를 설정할 수 있음을 보았습니다. 또는 EGLFS는'libinput'을 사용합니다. 어쨌든'evdev'와'libinput'에 명령 행 도구가있어 장치의 이름을 알아 내고 그 장치의 입력을 읽습니다. Qt가 사용하는 것을 볼 수있는'QT_LOGGING_RULES = qt.qpa.input = true' 변수가 있습니다. – Velkan

답변

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 = ""; 
       } 
      } 
     } 
    } 
}