title: How to read a file device in Linux using Qt?
body: <p>I'm working on a small Qt5-based GUI, which shall display a data stream from a Linux file device.
  For that I choose a joystick input. With <code>cat /dev/input/js0</code> it is possible to see the incoming stream on the terminal.</p>
  
  <p>Using C you can read this device file using a loop with a blocking read or handle the device signals. But I don't get this with Qt.</p>
  
  <p>What is the typical approach to interact with device files using Qt?</p>
  
  <hr>
  
  <p>Based on the answer of @rodrigo here a new implementation:</p>
  
  <p><em>joystick.h</em></p>
  
  <pre><code>#ifndef JOYSTICK_H
  #define JOYSTICK_H
  
  #include &lt;QObject&gt;
  #include &lt;QFile&gt;
  #include &lt;QSocketNotifier&gt;
  
  class Joystick
        : public QObject
  {
      Q_OBJECT
  
      QString fileName = "/dev/input/js0";
      QFile *file;
      QSocketNotifier *notifier;
  
  public:
      explicit Joystick(QObject *parent = nullptr);
      ~Joystick();
  
  signals:
  
  public slots:
      void handle_readNotification(int socket);
  };
  
  #endif // JOYSTICK_H
  </code></pre>
  
  <p><em>joystick.cpp</em></p>
  
  <pre><code>#include "joystick.h"
  
  Joystick::Joystick(QObject *parent)
     : QObject(parent)
  {
      file = new QFile();
      file-&gt;setFileName(fileName);
      if( !file-&gt;exists() ){
          qWarning("file does not exist");
          return;
      }
  
      if( !file-&gt;open(QFile::ReadOnly) ){
          qWarning("can not open file");
          return;
      }
  
      notifier = new QSocketNotifier( file-&gt;handle(),
                                      QSocketNotifier::Read,
                                      this);
  
      connect( notifier,
               &amp;QSocketNotifier::activated,
               this,
               &amp;Joystick::handle_readNotification );
  
      if( !notifier-&gt;isEnabled() ){
          qInfo("enable notifier");
          notifier-&gt;setEnabled(true);
      }
      qInfo("Joystick init ready");
  }
  
  void
  Joystick::handle_readNotification(int /*socket*/)
  {
      static quint64 cnt=0;
      qInfo("cnt: %d",cnt++);
  
      if( !(file-&gt;isOpen()) ){
          qWarning("file closed");
          return;
      }
  
      char buf[16]; /* tested with different sizes */
      if( file-&gt;read(buf,sizeof(buf)) ){
          qInfo("read: %s",buf);
      }
  //  QByteArray ba = file-&gt;readAll();
  //  qInfo("Data: %s", ba.data());
  }
  </code></pre>
  
  <p>Then I run this, the last out put is <code>cnt: 0</code>. It seems, that the <code>read</code> or <code>readAll</code> call now blocks. If I comment out the read calls the counter runs very fast. <a href="https://stackoverflow.com/questions/23989477/qsocketnotifier-and-qfilereadall">here a similiar post</a> That is wrong here?</p>
  
  <hr>
  
  <h2>final solution</h2>
  
  <p>Thanks to rodrigo!</p>
  
  <p><em>joystick.h</em></p>
  
  <pre><code>#ifndef JOYSTICK_H
  #define JOYSTICK_H
  
  #include &lt;QObject&gt;
  #include &lt;QFile&gt;
  #include &lt;QSocketNotifier&gt;
  
  class Joystick
        : public QObject
  {
      Q_OBJECT
  
      QString fileName = "/dev/input/js0";
      QSocketNotifier *notifier;
      int fd;
  
  public:
      explicit Joystick(QObject *parent = nullptr);
      ~Joystick();
  
  signals:
      void buttonPressed(quint8 number, qint16 value);
      void axisMoved(quint8 number, qint16 value);
  
  
  public slots:
      void handle_readNotification(int socket);
  };
  
  #endif // JOYSTICK_H
  </code></pre>
  
  <p><em>joystick.cpp</em></p>
  
  <pre><code>#include "joystick.h"
  
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;linux/joystick.h&gt;
  
  Joystick::Joystick(QObject *parent)
     : QObject(parent)
  {
      auto file = new QFile();
      file-&gt;setFileName(fileName);
      if( !file-&gt;exists() ){
          qWarning("file does not exist");
          return;
      }
  
      fd = open(fileName.toUtf8().data(), O_RDONLY|O_NONBLOCK);
      if( fd==-1 ){
          qWarning("can not open file");
          return;
      }
  
      notifier = new QSocketNotifier( fd,
                                      QSocketNotifier::Read,
                                      this);
  
      connect( notifier,
               &amp;QSocketNotifier::activated,
               this,
               &amp;Joystick::handle_readNotification );
  }
  
  Joystick::~Joystick()
  {
      if( fd&gt;=0 ){
          close(fd);
      }
  }
  
  void
  Joystick::handle_readNotification(int /*socket*/)
  {
      struct js_event buf;
      while( read(fd,&amp;buf,sizeof(buf))&gt;0 ){
          switch (buf.type) {
          case JS_EVENT_BUTTON:
              emit buttonPressed(buf.number, buf.value);
              break;
          case JS_EVENT_AXIS:
              emit axisMoved(buf.number, buf.value);
              break;
          }
      }
  }
  </code></pre>