如何子类化QIODevice并读取/ dev / input / eventX

时间:2018-03-21 09:38:38

标签: qt

我已经阅读了QIODevice文档,但仍然不知道如何归档。 我想要做的是创建一个源自QIODevice的KeyBoard类。打开/ dev / input / eventX。我希望我的代码可以使用KeyBoard的readyRead()信号。 (QFile不发出readyRead()信号)

class KeyBoard : public QIODevice {
public:
    KeyBoard();
    ~KeyBoard();
protected:
    qint64 readData(char *data, qint64 size);
    qint64 writeData(const char *data, qint64 size);
};

我需要在readData()和writeData()中做些什么? 我的代码如何使用这个类? (我只使用QCoreApplication,没有gui)

1 个答案:

答案 0 :(得分:1)

在打开的文件句柄上使用QSocketNotifier。您可以使用QFile从设备中读取,也可以滥用QSerialPort,即QSerialPort m_port{"input/eventX"}。有关将QSocketNotifier与stdin一起使用的示例,请参阅this answer; /dev/input/eventX需要采用类似的方法。

以下是适用于/dev/stdio的示例,但在/dev/input/eventX上的工作方式相同。

// https://github.com/KubaO/stackoverflown/tree/master/questions/dev-notifier-49402735
#include <QtCore>
#include <fcntl.h>
#include <boost/optional.hpp>

class DeviceFile : public QFile {
   Q_OBJECT
   boost::optional<QSocketNotifier> m_notifier;
public:
   DeviceFile() {}
   DeviceFile(const QString &name) : QFile(name) {}
   DeviceFile(QObject * parent = {}) : QFile(parent) {}
   DeviceFile(const QString &name, QObject *parent) : QFile(name, parent) {}
   bool open(OpenMode flags) override {
      return
            QFile::isOpen()
            || QFile::open(flags)
            && fcntl(handle(), F_SETFL, O_NONBLOCK) != -1
            && (m_notifier.emplace(this->handle(), QSocketNotifier::Read, this), true)
            && m_notifier->isEnabled()
            && connect(&*m_notifier, &QSocketNotifier::activated, this, &QIODevice::readyRead)
            || (close(), false);
   }
   void close() override {
      m_notifier.reset();
      QFile::close();
   }
};

int main(int argc, char **argv) {
   QCoreApplication app{argc, argv};
   DeviceFile dev("/dev/stdin");
   QObject::connect(&dev, &QIODevice::readyRead, [&]{
      qDebug() << "*";
      if (dev.readAll().contains('q'))
         app.quit();
   });
   if (dev.open(QIODevice::ReadOnly))
      return app.exec();
}

#include "main.moc"