2017-02-16 71 views
3

我正在Qt的一個樹莓派項目上工作。我有一個USB鍵盤和一個USB讀卡器(讀取爲鍵盤)插入。我需要能夠隔離讀卡器輸入,以便它不能用於填充常規文本框並且讀取方式不同信用卡信息。兩者似乎都將他們的文件作爲hidraw項目放在/ dev中,儘管它們的排序是隨機的。有沒有辦法,我可以從另一個程序隔離一個?預先感謝任何幫助!Qt C++隔離鍵盤

+0

嘗試'evrouter'。它可以根據設備名稱過濾輸入事件。 (如果您使用完整的X環境) – Velkan

+0

Darn,因爲我使用EGLFS,所以我不在X環境中。雖然謝謝! – Nick

+1

也許它使用'evdev'。我已經看到你可以傳入一個環境變量來設置使用哪個設備。或者,也許EGLFS使用'libinput'。無論哪種方式,在'evdev'和'libinput'中都有命令行工具來計算設備的名稱並從中讀取輸入。有'QT_LOGGING_RULES = qt.qpa.input = true'變量能夠看到什麼Qt使用。 – 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 = ""; 
       } 
      } 
     } 
    } 
}