【问题标题】:How to subclass QIODevice and read /dev/input/eventX如何继承 QIODevice 并读取 /dev/input/eventX
【发布时间】:2018-03-21 09:38:37
【问题描述】:

我已阅读 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)

【问题讨论】:

    标签: qt


    【解决方案1】:

    在打开的文件句柄上使用QSocketNotifier。您可以使用QFile从设备读取,或滥用QSerialPort,即QSerialPort m_port{"input/eventX"}。请参阅this answer 以获取将QSocketNotifier 与标准输入一起使用的示例; /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"
    

    【讨论】:

    • 我已经阅读了 QSocketNotifier 文档。这似乎是我想要的。谢谢!
    猜你喜欢
    • 2015-01-30
    • 1970-01-01
    • 2020-10-02
    • 2020-06-26
    • 2023-03-22
    • 2015-02-14
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多