[PyQt] stdin processing

Tom Dossis td at yoma.com.au
Thu Nov 8 02:14:12 GMT 2007

On 07/11/2007, at 2:08 AM, Vladimir Pouzanov wrote:

> Is there any way to read stdin line by line without blocking? My  
> application
> receives data over stdin (one command per line) and should react  
> immediately.
> I've tried to make such thing:
>     self.stdin = QtCore.QFile(self)
>     self.stdin.open(0, QtCore.QIODevice.ReadOnly)
>     self.connect(self.stdin, Qt.SIGNAL('readyRead()'),  
> self.on_stdinReadyRead)
> buy readyRead never fires.
> Then I've added
>     self.qsn = QtCore.QSocketNotifier(0,  
> QtCore.QSocketNotifier.Read, self)
>     self.connect(self.qsn, Qt.SIGNAL('activated(int)'), self.on_qsn)
> and made on_qsn() call on_stdinReadyRead. It works but there's  
> another problem:
> self.stdin.canReadLine() never returns true, and readAll() blocks  
> forever.

I get the same problem in the following doctest.
Also I don't see the bytesWritten signal either.

Test QFile Signals:

     >>> import os
     >>> from PyQt4.Qt import QApplication, QObject, SIGNAL
     >>> from PyQt4.QtCore import QFile, QIODevice

Setup a receiver for the 'readReady()' signal:

     >>> def handler(*args):
     ...     print 'handler', args

Create a pair of QFile objects to read/write from/to a pipe:

     >>> fdin, fdout = os.pipe()

     >>> qin = QFile()
     >>> QObject.connect(qin, SIGNAL('readyRead()'), handler)
     >>> qin.open(fdin, QIODevice.ReadOnly)

     >>> qout = QFile()
     >>> QObject.connect(qout, SIGNAL('bytesWritten(qint64)'), handler)
     >>> QObject.connect(qout, SIGNAL('aboutToClose()'), handler)
     >>> qout.open(fdout, QIODevice.WriteOnly)

Send some data to the QFile object's input:

     >>> qout.write('hello')
     >>> qout.flush()

Expected a bytesWritten signal, maybe it needs some event processing...

     >>> QApplication.processEvents()


Important - must close the writer fd, otherwise the upcoming readAll
will block (unlike calling os.read directly):

     >>> qout.close()
     handler ()

Looks like the aboutToClose signal happened!

     >>> os.close(fdout)

Shouldn't this be 5L rather than 0L?

     >>> qin.bytesAvailable()

     >>> str(qin.readAll())

No sign of the readReady signal, maybe it's tied to event processing?

     >>> QApplication.processEvents()


Tidy up:
     >>> qin.close()
     >>> os.close(fdin)

More information about the PyQt mailing list