如何在 Linux 上使用 Qt 读取 HID 设备 (/dev/hidrawX)?

Posted

技术标签:

【中文标题】如何在 Linux 上使用 Qt 读取 HID 设备 (/dev/hidrawX)?【英文标题】:How to read HID devices (/dev/hidrawX) with Qt on Linux? 【发布时间】:2013-07-14 19:04:29 【问题描述】:

我正在开发一种“RepRap 校准工具”,该工具将使用连接到打印平台的鼠标来测量平台的移动。

现在我无法从 /dev/hidrawX 读取原始鼠标数据,但我无法读取任何数据。

到目前为止我已经尝试过:

第一次尝试:

QFile f("/dev/hidraw0");
f.readAll();

什么都不读。

第二次尝试:

m_file = new QFile("/dev/hidraw0");
m_sn= new QSocketNotifier(m_file->handle(), QSocketNotifier::Read);
m_sn->setEnabled(true);
connect(m_sn, SIGNAL(activated(int)), this, SLOT(readyRead()));

然后在readyRead SLOT上:

qDebug()<<"Ready Read!!"<<m_file.bytesAvailable();
QTextStream d(&m_file);
qDebug()<< d.read(64);

这段代码触发readyRead槽一次,但它卡在read(64)调用上,如果我注释read(64),每次鼠标移动时都会触发槽。 m_file.bytesAvailable() 总是报告 0。

使用 Qt 读取这些设备的正确方法是什么?

解决方案:

我修改了如下代码:

bool rcMouseHandler::openHidraw(QString device)

    int fd =open(device.toLocal8Bit(),O_NONBLOCK);
    if(fd <=0)
    
        qDebug()<<"[WARN]rcMouseHandler::open-> Cant open!";
        return false;
    
    m_sn= new QSocketNotifier(fd, QSocketNotifier::Read);
    m_sn->setEnabled(true);
    connect(m_sn, SIGNAL(activated(int)), this, SLOT(readyRead()));
    return true;


void rcMouseHandler::readyRead()

    qDebug()<<"Ready Read!!";
    char buffer[4] = 0,0,0,0;
    read(m_sn->socket(),&buffer,4);
    qDebug()<<(quint8)buffer[0]<<(quint8)buffer[1]<<(quint8)buffer[2]<<(quint8)buffer[3];

【问题讨论】:

【参考方案1】:

我认为这里不使用 Qt 的正确方法。当您的这部分代码不可移植(与 /dev/* 一起使用的部分)时,为什么需要打开和读取 POSIX 之上的便携式包装器。在 O_NONBLOCK 中用“open”“man 2 open”打开设备并调用“read”(man 2 read)从中获取数据。而且您仍然可以使用带有返回“open”的句柄的 QSocketNotifier。

【讨论】:

谢谢!这解决了我的问题:) 实际上我不需要便携式解决方案来读取鼠标,我将只使用 linux。只是认为 QT 应该有一些东西来管理这种情况。 很久以前我想通过 RS232 使用设备时遇到了同样的问题。现在 qt5 有 qserial 类,当时(几年前)有第 3 方解决方案(他们继承 QIODevice 并做魔法),我花了几个小时调试协议 + 这个第三方库,最后,我只是切换到“打开+阅读”,一切都变得健壮了。 Qt 解决一般问题,QFile 用于常规文件。

以上是关于如何在 Linux 上使用 Qt 读取 HID 设备 (/dev/hidrawX)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Qt 在 Linux 中读取文件设备?

QT如何设置可变的全局变量

当我在 Windows 上的 HID 设备上执行 ReadFile() 时会发生啥?

在 Windows 应用商店应用中读取 HID 代理卡

使用 hid.dll API 从 HID 设备读取制造商字符串时遇到问题

如何从 C++/Qt 中的 .exe 和 .dlls 中读取图标(在 Windows 上)?