Hi,

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.

Your story sounds a lot like the world of confusion and pain I found myself in when I wanted to read a pipe in an async way. I couldn't find a way that actually worked in a decent way. Here is my non-decent way of reading a pipe. Pure distilled madness.


-----------------------------------------------
#!/usr/bin/python
import os
import sys
import time

from PyQt4 import QtCore

# Frequency to poll the file for more data.
POLL_INTERVAL = 250 #ms

# Maximum amount of time to use reading logs without returning to the main event loop.
MAX_TIME_SLICE=  0.1    # seconds

class LogReader(QtCore.QObject):
    def __init__(self, filename):
        QtCore.QObject.__init__(self)
        self.filename = filename

        self.log_file = None
        self.connectToFile()

    def connectToFile(self):
        if self.log_file is not None:
            gobject.source_remove(self.log_event_source)
            self.log_file.close()
            self.log_file = None

        self.log_file_fd = os.open(self.filename,os.O_RDONLY|os.O_NONBLOCK)
        self.log_file = os.fdopen(self.log_file_fd,"r")
        self.timer_id = self.startTimer(0)

    def timerEvent(self,event):
        if event.timerId()==self.timer_id:
            self.killTimer(self.timer_id)
            self.timer_id = None
            self.fileReady()
        else:
            QObject.timerEvent(self,event)

    def fileReady(self):
        try:
            enter_time = time.time()
            restart_time = POLL_INTERVAL
            while True:
                data = self.log_file.readline()
                if data=="":
                    break
                self.emit(QtCore.SIGNAL("newLine"), data)

                new_time = time.time()
                if (new_time-enter_time) > MAX_TIME_SLICE:
                    restart_time = 0
                    break

            self.timer_id = self.startTimer(restart_time)

        except IOError,e:
            self.connectToFile()

    def handleLine(self, line):
        print line

def main():
    app = QtCore.QCoreApplication(sys.argv)
    log_reader = LogReader("/var/log/messages")
    app.exec_()

if __name__=="__main__":
    main()
-----------------------------------------------

--
Simon Edwards             | KDE-NL, Guidance tools, Guarddog Firewall
[EMAIL PROTECTED]       | http://www.simonzone.com/software/
Nijmegen, The Netherlands | "ZooTV? You made the right choice."
_______________________________________________
PyQt mailing list    [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to