[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)
True
>>> qin.open(fdin, QIODevice.ReadOnly)
True
>>> qout = QFile()
>>> QObject.connect(qout, SIGNAL('bytesWritten(qint64)'), handler)
True
>>> QObject.connect(qout, SIGNAL('aboutToClose()'), handler)
True
>>> qout.open(fdout, QIODevice.WriteOnly)
True
Send some data to the QFile object's input:
>>> qout.write('hello')
5L
>>> qout.flush()
True
Expected a bytesWritten signal, maybe it needs some event processing...
>>> QApplication.processEvents()
Nope?
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()
0L
>>> str(qin.readAll())
'hello'
No sign of the readReady signal, maybe it's tied to event processing?
>>> QApplication.processEvents()
Nope!
Tidy up:
>>> qin.close()
>>> os.close(fdin)
More information about the PyQt
mailing list