我已经阅读了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)
答案 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"